-
Notifications
You must be signed in to change notification settings - Fork 648
Add automatic uv installation and improve dependency setup flow #584
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
base: main
Are you sure you want to change the base?
Conversation
Reviewer's GuideImplements cross-platform automatic installation of the uv package manager, wires it into both the MCP setup window and local server startup flow, and fixes uv path resolution so missing binaries are correctly detected and can trigger the new install path. Sequence diagram for automatic uv installation during local server startupsequenceDiagram
actor User
participant UnityEditor
participant ServerManagementService
participant DependencyManager
participant IPlatformDetector as PlatformDetector
User->>UnityEditor: Click Start Local HTTP Server
UnityEditor->>ServerManagementService: StartLocalHttpServer()
ServerManagementService->>DependencyManager: GetCurrentPlatformDetector()
DependencyManager-->>ServerManagementService: PlatformDetector
ServerManagementService->>PlatformDetector: DetectUv()
PlatformDetector-->>ServerManagementService: uvStatus(IsAvailable = false)
ServerManagementService->>UnityEditor: EditorUtility.DisplayDialog("uv Package Manager Missing")
alt User selects Install uv
ServerManagementService->>PlatformDetector: InstallUv()
PlatformDetector-->>ServerManagementService: success or failure
alt InstallUv success
ServerManagementService->>PlatformDetector: DetectUv()
PlatformDetector-->>ServerManagementService: uvStatus(IsAvailable)
alt uv still not detected
ServerManagementService->>UnityEditor: EditorUtility.DisplayDialog("Installation Incomplete")
ServerManagementService-->>UnityEditor: return false
else uv detected
ServerManagementService->>ServerManagementService: Continue startup flow
ServerManagementService-->>UnityEditor: Start server (success path)
end
else InstallUv failed
ServerManagementService->>PlatformDetector: GetUvInstallUrl()
PlatformDetector-->>ServerManagementService: uvInstallUrl
ServerManagementService->>UnityEditor: EditorUtility.DisplayDialog("Installation Failed", uvInstallUrl)
ServerManagementService-->>UnityEditor: return false
end
else User cancels
ServerManagementService-->>UnityEditor: return false
end
Updated class diagram for platform detectors and dependency setup flowclassDiagram
class IPlatformDetector {
<<interface>>
+string GetPythonInstallUrl()
+string GetUvInstallUrl()
+string GetInstallationRecommendations()
+bool InstallUv()
+DependencyStatus DetectPython()
+DependencyStatus DetectUv()
}
class PlatformDetectorBase {
<<abstract>>
+string GetPythonInstallUrl()
+string GetUvInstallUrl()
+string GetInstallationRecommendations()
+bool InstallUv()
+DependencyStatus DetectPython()
+DependencyStatus DetectUv()
}
class WindowsPlatformDetector {
+string GetPythonInstallUrl()
+string GetUvInstallUrl()
+string GetInstallationRecommendations()
+bool InstallUv()
+DependencyStatus DetectPython()
+DependencyStatus DetectUv()
}
class MacOSPlatformDetector {
+string GetPythonInstallUrl()
+string GetUvInstallUrl()
+string GetInstallationRecommendations()
+bool InstallUv()
+DependencyStatus DetectPython()
+DependencyStatus DetectUv()
}
class LinuxPlatformDetector {
+string GetPythonInstallUrl()
+string GetUvInstallUrl()
+string GetInstallationRecommendations()
+bool InstallUv()
+DependencyStatus DetectPython()
+DependencyStatus DetectUv()
}
class DependencyManager {
+IPlatformDetector GetCurrentPlatformDetector()
+DependencyCheckResult CheckAllDependencies()
}
class DependencyStatus {
+string Name
+bool IsRequired
+bool IsAvailable
}
class DependencyCheckResult {
+List~DependencyStatus~ Dependencies
}
class MCPSetupWindow {
-Label installationInstructions
-Button openPythonLinkButton
-Button openUvLinkButton
-Button autoInstallUvButton
-Button refreshButton
-Button doneButton
-DependencyCheckResult _dependencyResult
+void CreateGUI()
+void OnOpenPythonInstallClicked()
+void OnOpenUvInstallClicked()
+void OnAutoInstallUvClicked()
+void UpdateUI()
}
class ServerManagementService {
+bool StartLocalHttpServer()
+bool TryGetLocalHttpServerCommandParts()
}
class PathResolverService {
+string GetUvxPath()
}
IPlatformDetector <|-- PlatformDetectorBase
PlatformDetectorBase <|-- WindowsPlatformDetector
PlatformDetectorBase <|-- MacOSPlatformDetector
PlatformDetectorBase <|-- LinuxPlatformDetector
DependencyManager --> IPlatformDetector : uses
DependencyManager --> DependencyCheckResult : returns
DependencyCheckResult --> DependencyStatus : contains
MCPSetupWindow --> DependencyManager : uses
MCPSetupWindow --> DependencyCheckResult : holds
ServerManagementService --> DependencyManager : uses
ServerManagementService --> PathResolverService : uses
Flow diagram for uv detection and installation logicflowchart TD
A[Start local server or click Install UV Automatically] --> B[GetCurrentPlatformDetector]
B --> C[DetectUv]
C --> D{uv available?}
D -->|Yes| E[Proceed with normal flow]
D -->|No| F{User chooses automatic install?}
F -->|No| G[Abort operation]
F -->|Yes| H[PlatformDetector.InstallUv]
H --> I{Install succeeded?}
I -->|No| J[Show Installation Failed dialog]
J --> G
I -->|Yes| K[Re run DetectUv]
K --> L{uv now detected?}
L -->|Yes| E
L -->|No| M[Show Installation Incomplete dialog]
M --> G
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
📝 WalkthroughWalkthroughThis PR adds automatic uv package manager installation capability across all platforms by introducing an Changes
Sequence DiagramsequenceDiagram
participant User
participant MCPSetupWindow
participant DependencyManager
participant PlatformDetector
participant Shell
User->>MCPSetupWindow: Click "Install UV Automatically"
MCPSetupWindow->>DependencyManager: GetCurrentPlatformDetector()
DependencyManager-->>MCPSetupWindow: PlatformDetector instance
MCPSetupWindow->>PlatformDetector: InstallUv()
PlatformDetector->>Shell: Execute platform-specific install command
Shell-->>PlatformDetector: Exit code (0=success)
PlatformDetector-->>MCPSetupWindow: bool (true/false)
MCPSetupWindow->>MCPSetupWindow: CheckAllDependencies()
alt Installation Success
MCPSetupWindow->>User: Show success dialog
else Incomplete Installation
MCPSetupWindow->>User: Warn restart Unity needed
else Installation Failed
MCPSetupWindow->>User: Show failure dialog with install URL
end
MCPSetupWindow->>MCPSetupWindow: UpdateUI()
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - I've found 5 issues, and left some high level feedback:
- The InstallUv implementations on Windows/macOS/Linux synchronously wait up to 60 seconds on an external process, which will block the Unity editor UI; consider running these installs asynchronously (e.g., with a progress dialog) or at least making the timeout configurable and surfacing progress to the user.
- The curl-based InstallUv logic for macOS and Linux is duplicated; you could extract a shared helper in PlatformDetectorBase (or a small utility) to avoid repeating the /bin/sh + curl command and error handling.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The InstallUv implementations on Windows/macOS/Linux synchronously wait up to 60 seconds on an external process, which will block the Unity editor UI; consider running these installs asynchronously (e.g., with a progress dialog) or at least making the timeout configurable and surfacing progress to the user.
- The curl-based InstallUv logic for macOS and Linux is duplicated; you could extract a shared helper in PlatformDetectorBase (or a small utility) to avoid repeating the /bin/sh + curl command and error handling.
## Individual Comments
### Comment 1
<location> `MCPForUnity/Editor/Dependencies/PlatformDetectors/WindowsPlatformDetector.cs:103-112` </location>
<code_context>
Note: Make sure ~/.local/bin is in your PATH for user-local installations.";
}
+ public override bool InstallUv()
+ {
+ try
+ {
+ McpLog.Info("Attempting to install uv package manager via curl...");
+
+ var psi = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = "/bin/sh",
+ Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"",
+ UseShellExecute = false,
+ CreateNoWindow = false
+ };
+
+ using var process = System.Diagnostics.Process.Start(psi);
+ if (process == null) return false;
+
+ process.WaitForExit(60000);
+
+ return process.ExitCode == 0;
+ }
+ catch (Exception ex)
</code_context>
<issue_to_address>
**issue (bug_risk):** Handle long-running installs and potential timeout behavior more robustly.
`process.WaitForExit(60000)` can leave the process running and cause `process.ExitCode` to throw if the install takes longer than 60s. It also risks flaky failures on slower machines.
Please check the return value of `WaitForExit` and handle timeouts explicitly (e.g., log and return failure), and consider either a longer or configurable timeout (or no timeout with appropriate UI feedback) to avoid premature failures.
</issue_to_address>
### Comment 2
<location> `MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs:95-104` </location>
<code_context>
Note: Make sure ~/.local/bin is in your PATH for user-local installations.";
}
+ public override bool InstallUv()
+ {
+ try
+ {
+ McpLog.Info("Attempting to install uv package manager via curl...");
+
+ var psi = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = "/bin/sh",
+ Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"",
+ UseShellExecute = false,
+ CreateNoWindow = false
+ };
+
+ using var process = System.Diagnostics.Process.Start(psi);
+ if (process == null) return false;
+
+ process.WaitForExit(60000);
+
+ return process.ExitCode == 0;
+ }
+ catch (Exception ex)
</code_context>
<issue_to_address>
**issue (bug_risk):** Avoid blocking indefinitely on the installer and hard-coding a short timeout.
`WaitForExit(60000)` has the same issues as on Windows:
- A slow download/install can exceed 60s, causing a timeout and possible `InvalidOperationException` when reading `ExitCode`.
- 60s may be too short for users on slow networks.
Please check the `WaitForExit` return value and handle timeouts explicitly (e.g., log and return `false`), and consider a longer/parameterized timeout or waiting without a timeout while showing progress. The same logic applies to macOS, so a shared helper would help keep behavior consistent across platforms.
</issue_to_address>
### Comment 3
<location> `MCPForUnity/Editor/Windows/MCPSetupWindow.cs:119-117` </location>
<code_context>
Application.OpenURL(uvUrl);
}
+ private void OnAutoInstallUvClicked()
+ {
+ var detector = DependencyManager.GetCurrentPlatformDetector();
+ if (detector.InstallUv())
+ {
+ _dependencyResult = DependencyManager.CheckAllDependencies();
+ UpdateUI();
+
+ var uvDep = _dependencyResult.Dependencies.Find(d => d.Name == "uv Package Manager");
+ if (uvDep != null && !uvDep.IsAvailable)
+ {
+ EditorUtility.DisplayDialog(
+ "Installation Incomplete",
+ "uv was installed, but it is not yet detected in the current process PATH. " +
+ "You may need to restart Unity for the changes to take effect.",
+ "OK");
+ }
+ else
+ {
</code_context>
<issue_to_address>
**suggestion (performance):** Running the installer synchronously on the UI thread may freeze the Unity editor for up to a minute.
`OnAutoInstallUvClicked` calls `detector.InstallUv()` synchronously on the main editor thread, and platform implementations can block for up to 60 seconds, making the editor appear hung.
Please move the installation to a background task and surface progress via `EditorUtility.DisplayProgressBar` or a similar mechanism so the UI stays responsive. If full async handling isn’t feasible, at least show a clear, modal progress dialog indicating that a long-running operation is in progress to discourage users from force-quitting the editor.
Suggested implementation:
```csharp
// Run uv installation off the main thread and surface progress so the editor stays responsive.
private async void OnAutoInstallUvClicked()
{
var detector = DependencyManager.GetCurrentPlatformDetector();
try
{
// Show a modal progress bar so it's clear a long-running operation is in progress.
EditorUtility.DisplayProgressBar(
"Installing uv",
"Installing uv Package Manager. This may take up to a minute...",
0.5f);
// Run the installer on a background thread to avoid freezing the editor UI.
var installSucceeded = await System.Threading.Tasks.Task.Run(() => detector.InstallUv());
// Clear the progress bar as soon as the background work completes.
EditorUtility.ClearProgressBar();
if (installSucceeded)
{
_dependencyResult = DependencyManager.CheckAllDependencies();
UpdateUI();
var uvDep = _dependencyResult.Dependencies.Find(d => d.Name == "uv Package Manager");
if (uvDep != null && !uvDep.IsAvailable)
{
EditorUtility.DisplayDialog(
```
1. The SEARCH block above only includes the beginning of the original `OnAutoInstallUvClicked` method because the full method body was not visible in the snippet you provided. You should expand the SEARCH range to cover the *entire* original `OnAutoInstallUvClicked` method body (from the `private void OnAutoInstallUvClicked()` line down to its closing `}`) so it is completely replaced by the new async implementation.
2. The new method assumes the rest of the original logic after `EditorUtility.DisplayDialog(` remains the same (e.g., the "Installation Incomplete" dialog text and any `else` branch for the successful case). Ensure that the closing `)` / `;`, the `else` block (if any), and the method’s closing brace `}` are all present after the inserted `EditorUtility.DisplayDialog(` line.
3. If `System.Threading.Tasks` is not already imported at the top of `MCPForUnity/Editor/Windows/MCPSetupWindow.cs`, add:
```csharp
using System.Threading.Tasks;
```
This allows you to simplify the call to `Task.Run` (you can then replace `System.Threading.Tasks.Task.Run` with `Task.Run` if you prefer).
4. Make sure your project is using the .NET 4.x scripting runtime and API compatibility level so that `async`/`await` in editor code works correctly. If your codebase prefers not to use `async void`, you can instead enqueue completion logic back to the main thread with `EditorApplication.delayCall`, but that will require adjusting the method signature and event hookup accordingly.
</issue_to_address>
### Comment 4
<location> `MCPForUnity/Editor/Services/ServerManagementService.cs:415-424` </location>
<code_context>
+ private void OnAutoInstallUvClicked()
+ {
+ var detector = DependencyManager.GetCurrentPlatformDetector();
+ if (detector.InstallUv())
+ {
+ _dependencyResult = DependencyManager.CheckAllDependencies();
+ UpdateUI();
+
+ var uvDep = _dependencyResult.Dependencies.Find(d => d.Name == "uv Package Manager");
+ if (uvDep != null && !uvDep.IsAvailable)
+ {
+ EditorUtility.DisplayDialog(
+ "Installation Incomplete",
+ "uv was installed, but it is not yet detected in the current process PATH. " +
+ "You may need to restart Unity for the changes to take effect.",
+ "OK");
+ }
+ else
+ {
</code_context>
<issue_to_address>
**suggestion (performance):** Avoid blocking server startup on a potentially long-running interactive installer without clear feedback.
`detector.InstallUv()` can block for up to 60 seconds as part of starting the local HTTP server, which will freeze the editor with no in-editor indication of progress.
Consider:
- Showing an editor progress dialog during installation so users understand the delay.
- Separating the automatic install path from a “just start server” path, so users who know uv is missing aren’t forced into a long blocking operation when starting the server.
Suggested implementation:
```csharp
// Check if uv is installed, and offer to install if missing.
var detector = DependencyManager.GetCurrentPlatformDetector();
var uvStatus = detector.DetectUv();
if (!uvStatus.IsAvailable)
{
if (EditorUtility.DisplayDialog(
"uv Package Manager Missing",
"The 'uv' package manager is required to run the local MCP server, but it was not found in your PATH.\n\n" +
"An automatic installation can be attempted now. This may take up to 60 seconds while a local HTTP server is started.\n\n" +
"Alternatively, you can start the server without uv (if you plan to install it manually or are just inspecting the project).",
"Install uv (may take up to 60 seconds)",
"Start without uv"))
{
EditorUtility.DisplayProgressBar(
"Installing uv",
"Installing the 'uv' package manager. This may take up to 60 seconds...",
0.5f);
try
{
if (detector.InstallUv())
{
// Re-check after installation
}
}
finally
{
EditorUtility.ClearProgressBar();
}
```
The current control flow already effectively separates the “install uv” and “start without uv” paths: declining the dialog skips `InstallUv()` and continues with the rest of the method. If later code assumes uv is present, you may want to:
1. Explicitly handle the “start without uv” case (e.g., by skipping server startup or showing a more targeted warning when uv is still missing).
2. Optionally log or surface a non-blocking notification if the user chooses to start without uv, so they understand any subsequent failures are due to uv being absent.
</issue_to_address>
### Comment 5
<location> `MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs:93-102` </location>
<code_context>
Note: Make sure ~/.local/bin is in your PATH for user-local installations.";
}
+ public override bool InstallUv()
+ {
+ try
+ {
+ McpLog.Info("Attempting to install uv package manager via curl...");
+
+ var psi = new System.Diagnostics.ProcessStartInfo
+ {
+ FileName = "/bin/sh",
+ Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"",
+ UseShellExecute = false,
+ CreateNoWindow = false
+ };
+
+ using var process = System.Diagnostics.Process.Start(psi);
+ if (process == null) return false;
+
+ process.WaitForExit(60000);
+
+ return process.ExitCode == 0;
+ }
+ catch (Exception ex)
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Consider the security implications of piping remote installer scripts directly into a shell.
Both Linux and macOS `InstallUv` use `curl -LsSf https://astral.sh/uv/install.sh | sh`, which executes remote content without independent verification or an explicit confirmation step in the editor.
Given this runs inside the editor, consider:
- Logging the exact command and URL before execution.
- Downloading to a temporary file and optionally prompting the user to inspect/confirm before running it.
- Providing a setting to disable this automatic installer for security‑sensitive environments.
Suggested implementation:
```csharp
public override bool InstallUv()
{
try
{
const string installScriptUrl = "https://astral.sh/uv/install.sh";
// NOTE: This method intentionally logs the exact command and URL used so that
// users and security‑sensitive environments can audit what is being executed.
McpLog.Info($"Attempting to install uv package manager from '{installScriptUrl}'...");
// In security‑sensitive environments this automatic installer should be
// disabled via settings; see <additional_changes> for details.
// if (McpSettings.Current.DisableAutomaticInstallers)
// {
// McpLog.Info("Automatic uv installation is disabled by settings.");
// return false;
// }
// Optional confirmation prompt (requires UnityEditor):
// if (!UnityEditor.EditorUtility.DisplayDialog(
// "Install uv",
// $"The editor will download and execute the installer script from:\n\n{installScriptUrl}\n\nDo you want to continue?",
// "Install",
// "Cancel"))
// {
// McpLog.Info("User cancelled uv installation.");
// return false;
// }
// Download the installer script to a temporary file instead of piping directly to sh.
var tempScriptPath = System.IO.Path.Combine(
System.IO.Path.GetTempPath(),
$"uv-install-{Guid.NewGuid():N}.sh");
var downloadArguments =
$"-c \"curl -LsSf {installScriptUrl} -o '{tempScriptPath}'\"";
McpLog.Info($"Downloading uv installer script with: /bin/sh {downloadArguments}");
var downloadPsi = new System.Diagnostics.ProcessStartInfo
{
FileName = "/bin/sh",
Arguments = downloadArguments,
UseShellExecute = false,
CreateNoWindow = false
};
using (var downloadProcess = System.Diagnostics.Process.Start(downloadPsi))
{
if (downloadProcess == null)
{
McpLog.Error("Failed to start curl process to download uv installer.");
return false;
}
downloadProcess.WaitForExit(60000);
if (downloadProcess.ExitCode != 0 || !System.IO.File.Exists(tempScriptPath))
{
McpLog.Error($"curl failed to download uv installer (exit code {downloadProcess.ExitCode}).");
return false;
}
}
// Now execute the downloaded script.
var executeArguments = $"-c \"sh '{tempScriptPath}'\"";
McpLog.Info($"Executing uv installer script with: /bin/sh {executeArguments}");
var executePsi = new System.Diagnostics.ProcessStartInfo
{
FileName = "/bin/sh",
Arguments = executeArguments,
UseShellExecute = false,
CreateNoWindow = false
};
using (var executeProcess = System.Diagnostics.Process.Start(executePsi))
{
if (executeProcess == null)
{
McpLog.Error("Failed to start process to execute uv installer script.");
return false;
}
executeProcess.WaitForExit(600000); // allow more time for installation
if (executeProcess.ExitCode != 0)
{
McpLog.Error($"uv installer script exited with code {executeProcess.ExitCode}.");
return false;
}
}
// Best effort clean‑up of the temporary script
try
{
if (System.IO.File.Exists(tempScriptPath))
{
System.IO.File.Delete(tempScriptPath);
}
}
catch (Exception cleanupEx)
{
McpLog.Warn($"Failed to delete temporary uv installer script '{tempScriptPath}': {cleanupEx.Message}");
}
McpLog.Info("uv package manager installed successfully.");
return true;
}
catch (Exception ex)
{
McpLog.Error($"Failed to install uv: {ex.Message}");
return false;
}
}
```
` note since the settings system isn’t visible here).
Here are the concrete edits:
<file_operations>
<file_operation operation="edit" file_path="MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs">
<<<<<<< SEARCH
public override bool InstallUv()
{
try
{
McpLog.Info("Attempting to install uv package manager via curl...");
var psi = new System.Diagnostics.ProcessStartInfo
{
FileName = "/bin/sh",
Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"",
UseShellExecute = false,
CreateNoWindow = false
};
using var process = System.Diagnostics.Process.Start(psi);
if (process == null) return false;
process.WaitForExit(60000);
return process.ExitCode == 0;
}
catch (Exception ex)
{
McpLog.Error($"Failed to install uv: {ex.Message}");
return false;
}
}
=======
public override bool InstallUv()
{
try
{
const string installScriptUrl = "https://astral.sh/uv/install.sh";
// NOTE: This method intentionally logs the exact command and URL used so that
// users and security‑sensitive environments can audit what is being executed.
McpLog.Info($"Attempting to install uv package manager from '{installScriptUrl}'...");
// In security‑sensitive environments this automatic installer should be
// disabled via settings; see <additional_changes> for details.
// if (McpSettings.Current.DisableAutomaticInstallers)
// {
// McpLog.Info("Automatic uv installation is disabled by settings.");
// return false;
// }
// Optional confirmation prompt (requires UnityEditor):
// if (!UnityEditor.EditorUtility.DisplayDialog(
// "Install uv",
// $"The editor will download and execute the installer script from:\n\n{installScriptUrl}\n\nDo you want to continue?",
// "Install",
// "Cancel"))
// {
// McpLog.Info("User cancelled uv installation.");
// return false;
// }
// Download the installer script to a temporary file instead of piping directly to sh.
var tempScriptPath = System.IO.Path.Combine(
System.IO.Path.GetTempPath(),
$"uv-install-{Guid.NewGuid():N}.sh");
var downloadArguments =
$"-c \"curl -LsSf {installScriptUrl} -o '{tempScriptPath}'\"";
McpLog.Info($"Downloading uv installer script with: /bin/sh {downloadArguments}");
var downloadPsi = new System.Diagnostics.ProcessStartInfo
{
FileName = "/bin/sh",
Arguments = downloadArguments,
UseShellExecute = false,
CreateNoWindow = false
};
using (var downloadProcess = System.Diagnostics.Process.Start(downloadPsi))
{
if (downloadProcess == null)
{
McpLog.Error("Failed to start curl process to download uv installer.");
return false;
}
downloadProcess.WaitForExit(60000);
if (downloadProcess.ExitCode != 0 || !System.IO.File.Exists(tempScriptPath))
{
McpLog.Error($"curl failed to download uv installer (exit code {downloadProcess.ExitCode}).");
return false;
}
}
// Now execute the downloaded script.
var executeArguments = $"-c \"sh '{tempScriptPath}'\"";
McpLog.Info($"Executing uv installer script with: /bin/sh {executeArguments}");
var executePsi = new System.Diagnostics.ProcessStartInfo
{
FileName = "/bin/sh",
Arguments = executeArguments,
UseShellExecute = false,
CreateNoWindow = false
};
using (var executeProcess = System.Diagnostics.Process.Start(executePsi))
{
if (executeProcess == null)
{
McpLog.Error("Failed to start process to execute uv installer script.");
return false;
}
executeProcess.WaitForExit(600000); // allow more time for installation
if (executeProcess.ExitCode != 0)
{
McpLog.Error($"uv installer script exited with code {executeProcess.ExitCode}.");
return false;
}
}
// Best effort clean‑up of the temporary script
try
{
if (System.IO.File.Exists(tempScriptPath))
{
System.IO.File.Delete(tempScriptPath);
}
}
catch (Exception cleanupEx)
{
McpLog.Warn($"Failed to delete temporary uv installer script '{tempScriptPath}': {cleanupEx.Message}");
}
McpLog.Info("uv package manager installed successfully.");
return true;
}
catch (Exception ex)
{
McpLog.Error($"Failed to install uv: {ex.Message}");
return false;
}
}
>>>>>>> REPLACE
</file_operation>
</file_operations>
<additional_changes>
To fully implement the review suggestions, you may also want to:
1. **Add a setting to disable automatic installers** (e.g. in your existing settings/config system):
- Introduce a flag such as `bool DisableAutomaticInstallers` (or a more specific one like `DisableUvAutoInstall`) in your MCP/Editor settings.
- Respect that flag in `InstallUv()` where the commented `McpSettings.Current.DisableAutomaticInstallers` check is, and wire it to your UI/preferences.
2. **Optional confirmation prompt**:
- If you want the confirmation dialog enabled by default, uncomment the `UnityEditor.EditorUtility.DisplayDialog` block and ensure `using UnityEditor;` is present at the top of the file (if not already).
- If you prefer no GUI prompt by default, consider adding a setting `RequireConfirmationForInstallers` and use that to guard the dialog.
3. **Cross‑platform consistency**:
- Apply the same pattern (download to temp file, log command/URL, optional confirmation and settings check) to the Linux and any other platform `InstallUv` implementations so behavior is consistent across platforms.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| public override bool InstallUv() | ||
| { | ||
| try | ||
| { | ||
| McpLog.Info("Attempting to install uv package manager via PowerShell..."); | ||
|
|
||
| var psi = new System.Diagnostics.ProcessStartInfo | ||
| { | ||
| FileName = "powershell.exe", | ||
| Arguments = "-NoProfile -ExecutionPolicy ByPass -Command \"irm https://astral.sh/uv/install.ps1 | iex\"", |
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.
issue (bug_risk): Handle long-running installs and potential timeout behavior more robustly.
process.WaitForExit(60000) can leave the process running and cause process.ExitCode to throw if the install takes longer than 60s. It also risks flaky failures on slower machines.
Please check the return value of WaitForExit and handle timeouts explicitly (e.g., log and return failure), and consider either a longer or configurable timeout (or no timeout with appropriate UI feedback) to avoid premature failures.
| var detector = DependencyManager.GetCurrentPlatformDetector(); | ||
| var uvStatus = detector.DetectUv(); | ||
| if (!uvStatus.IsAvailable) | ||
| { | ||
| if (EditorUtility.DisplayDialog( | ||
| "uv Package Manager Missing", | ||
| "The 'uv' package manager is required to run the local MCP server, but it was not found in your PATH.\n\n" + | ||
| "Would you like to attempt an automatic installation now?", | ||
| "Install uv", | ||
| "Cancel")) |
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.
suggestion (performance): Avoid blocking server startup on a potentially long-running interactive installer without clear feedback.
detector.InstallUv() can block for up to 60 seconds as part of starting the local HTTP server, which will freeze the editor with no in-editor indication of progress.
Consider:
- Showing an editor progress dialog during installation so users understand the delay.
- Separating the automatic install path from a “just start server” path, so users who know uv is missing aren’t forced into a long blocking operation when starting the server.
Suggested implementation:
// Check if uv is installed, and offer to install if missing.
var detector = DependencyManager.GetCurrentPlatformDetector();
var uvStatus = detector.DetectUv();
if (!uvStatus.IsAvailable)
{
if (EditorUtility.DisplayDialog(
"uv Package Manager Missing",
"The 'uv' package manager is required to run the local MCP server, but it was not found in your PATH.\n\n" +
"An automatic installation can be attempted now. This may take up to 60 seconds while a local HTTP server is started.\n\n" +
"Alternatively, you can start the server without uv (if you plan to install it manually or are just inspecting the project).",
"Install uv (may take up to 60 seconds)",
"Start without uv"))
{
EditorUtility.DisplayProgressBar(
"Installing uv",
"Installing the 'uv' package manager. This may take up to 60 seconds...",
0.5f);
try
{
if (detector.InstallUv())
{
// Re-check after installation
}
}
finally
{
EditorUtility.ClearProgressBar();
}The current control flow already effectively separates the “install uv” and “start without uv” paths: declining the dialog skips InstallUv() and continues with the rest of the method. If later code assumes uv is present, you may want to:
- Explicitly handle the “start without uv” case (e.g., by skipping server startup or showing a more targeted warning when uv is still missing).
- Optionally log or surface a non-blocking notification if the user chooses to start without uv, so they understand any subsequent failures are due to uv being absent.
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: 3
🤖 Fix all issues with AI agents
In `@MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs`:
- Around line 95-121: The InstallUv method blocks the main thread and doesn't
handle WaitForExit timeouts safely; update InstallUv to run asynchronously or be
invoked from a background thread (e.g., Task.Run) so editor UI isn't blocked,
and change its process-wait logic to check the boolean result of
process.WaitForExit(timeout) before reading process.ExitCode—if WaitForExit
returns false, kill/Dispose the child process (Process.Kill/Close) and return
false, and ensure exceptions are logged with full details in the catch; update
callers (MCPSetupWindow and ServerManagementService) to await or otherwise
offload the async/background InstallUv invocation.
In `@MCPForUnity/Editor/Services/ServerManagementService.cs`:
- Around line 414-453: The current call to detector.InstallUv() in the
ServerManagementService flow blocks the Unity main thread (via
process.WaitForExit), so wrap the installation with a user-visible progress
indicator and ensure the progress bar is cleared regardless of outcome: before
calling InstallUv() show EditorUtility.DisplayProgressBar("Installing uv",
"Please wait while uv is being installed...", 0.5f), call detector.InstallUv(),
then always call EditorUtility.ClearProgressBar() in a finally block, and only
after successful return call DetectUv() again; alternatively refactor
InstallUv() on the platform detector to an async/polled API and drive it via
EditorApplication.update instead of calling InstallUv() synchronously so the UI
remains responsive.
In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs`:
- Around line 119-151: OnAutoInstallUvClicked currently calls
DependencyManager.GetCurrentPlatformDetector().InstallUv() on the main thread
which can block the Unity Editor; change this to run the long-running
InstallUv() off the main thread (e.g. Task.Run or a background thread) while
showing EditorUtility.DisplayProgressBar and allowing cancelation, then marshal
back to the main thread to set _dependencyResult =
DependencyManager.CheckAllDependencies(), call UpdateUI(), clear the progress
bar, and show the appropriate EditorUtility.DisplayDialog results; ensure you
reference the existing symbols OnAutoInstallUvClicked,
DependencyManager.GetCurrentPlatformDetector(), InstallUv(), _dependencyResult,
DependencyManager.CheckAllDependencies(), UpdateUI(), and
EditorUtility.DisplayProgressBar/DisplayDialog when implementing the
async/background flow and main-thread UI updates.
♻️ Duplicate comments (2)
MCPForUnity/Editor/Dependencies/PlatformDetectors/MacOSPlatformDetector.cs (1)
93-119: Same timeout + UI-thread blocking risk as Linux InstallUv().MCPForUnity/Editor/Dependencies/PlatformDetectors/WindowsPlatformDetector.cs (1)
103-129: Same timeout + UI-thread blocking risk as Linux/macOS InstallUv().
| public override bool InstallUv() | ||
| { | ||
| try | ||
| { | ||
| McpLog.Info("Attempting to install uv package manager via curl..."); | ||
|
|
||
| var psi = new System.Diagnostics.ProcessStartInfo | ||
| { | ||
| FileName = "/bin/sh", | ||
| Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"", | ||
| UseShellExecute = false, | ||
| CreateNoWindow = false | ||
| }; | ||
|
|
||
| using var process = System.Diagnostics.Process.Start(psi); | ||
| if (process == null) return false; | ||
|
|
||
| process.WaitForExit(60000); | ||
|
|
||
| return process.ExitCode == 0; | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| McpLog.Error($"Failed to install uv: {ex.Message}"); | ||
| return false; | ||
| } | ||
| } |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find all call sites of InstallUv
rg -n --type=cs 'InstallUv\s*\(' MCPForUnity/Repository: CoplayDev/unity-mcp
Length of output: 831
🏁 Script executed:
#!/bin/bash
# Get more context around the file to understand the class and its usage
cat -n MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs | head -120 | tail -40Repository: CoplayDev/unity-mcp
Length of output: 1748
🏁 Script executed:
#!/bin/bash
# Search for the class definition and any threading-related patterns
rg -n --type=cs 'class LinuxPlatformDetector' MCPForUnity/ -A 5Repository: CoplayDev/unity-mcp
Length of output: 749
🏁 Script executed:
#!/bin/bash
# Examine MCPSetupWindow.cs around line 122
cat -n MCPForUnity/Editor/Windows/MCPSetupWindow.cs | sed -n '110,135p'Repository: CoplayDev/unity-mcp
Length of output: 1284
🏁 Script executed:
#!/bin/bash
# Examine ServerManagementService.cs around line 426
cat -n MCPForUnity/Editor/Services/ServerManagementService.cs | sed -n '410,440p'Repository: CoplayDev/unity-mcp
Length of output: 1814
🏁 Script executed:
#!/bin/bash
# Check if there's any async/threading context in MCPSetupWindow
rg -n --type=cs 'async|Task|Thread|Dispatch|Main|UI' MCPForUnity/Editor/Windows/MCPSetupWindow.cs | head -20Repository: CoplayDev/unity-mcp
Length of output: 313
🏁 Script executed:
#!/bin/bash
# Check the method containing the call at ServerManagementService.cs:426
cat -n MCPForUnity/Editor/Services/ServerManagementService.cs | sed -n '390,410p'Repository: CoplayDev/unity-mcp
Length of output: 1181
🏁 Script executed:
#!/bin/bash
# Search for the method signature to understand threading
rg -n --type=cs 'public|private|async' MCPForUnity/Editor/Services/ServerManagementService.cs | grep -A 2 -B 2 '426'Repository: CoplayDev/unity-mcp
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Search for method definition containing line 426
cat -n MCPForUnity/Editor/Services/ServerManagementService.cs | sed -n '380,395p'Repository: CoplayDev/unity-mcp
Length of output: 855
🏁 Script executed:
#!/bin/bash
# Check if there's any async/await pattern in ServerManagementService
rg -n --type=cs 'async|Task|Coroutine' MCPForUnity/Editor/Services/ServerManagementService.cs | head -10Repository: CoplayDev/unity-mcp
Length of output: 232
Avoid blocking the editor and handle installer timeouts.
Both call sites (MCPSetupWindow.cs:122 and ServerManagementService.cs:426) execute InstallUv() on the main editor thread. The current implementation blocks for up to 60 seconds with WaitForExit(60000), freezing the UI.
Additionally, the code ignores the timeout result; if WaitForExit times out and returns false, accessing process.ExitCode throws InvalidOperationException, leaving the installer process running in the background. While caught by the outer try-catch, this silently returns false without cleaning up the orphaned process.
🔧 Safer timeout handling (still synchronous)
- process.WaitForExit(60000);
-
- return process.ExitCode == 0;
+ if (!process.WaitForExit(60000))
+ {
+ try { process.Kill(); } catch { /* best-effort */ }
+ return false;
+ }
+
+ return process.ExitCode == 0;Consider moving this operation to a background thread or async pattern to prevent UI hangs during installation.
📝 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.
| public override bool InstallUv() | |
| { | |
| try | |
| { | |
| McpLog.Info("Attempting to install uv package manager via curl..."); | |
| var psi = new System.Diagnostics.ProcessStartInfo | |
| { | |
| FileName = "/bin/sh", | |
| Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"", | |
| UseShellExecute = false, | |
| CreateNoWindow = false | |
| }; | |
| using var process = System.Diagnostics.Process.Start(psi); | |
| if (process == null) return false; | |
| process.WaitForExit(60000); | |
| return process.ExitCode == 0; | |
| } | |
| catch (Exception ex) | |
| { | |
| McpLog.Error($"Failed to install uv: {ex.Message}"); | |
| return false; | |
| } | |
| } | |
| public override bool InstallUv() | |
| { | |
| try | |
| { | |
| McpLog.Info("Attempting to install uv package manager via curl..."); | |
| var psi = new System.Diagnostics.ProcessStartInfo | |
| { | |
| FileName = "/bin/sh", | |
| Arguments = "-c \"curl -LsSf https://astral.sh/uv/install.sh | sh\"", | |
| UseShellExecute = false, | |
| CreateNoWindow = false | |
| }; | |
| using var process = System.Diagnostics.Process.Start(psi); | |
| if (process == null) return false; | |
| if (!process.WaitForExit(60000)) | |
| { | |
| try { process.Kill(); } catch { /* best-effort */ } | |
| return false; | |
| } | |
| return process.ExitCode == 0; | |
| } | |
| catch (Exception ex) | |
| { | |
| McpLog.Error($"Failed to install uv: {ex.Message}"); | |
| return false; | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@MCPForUnity/Editor/Dependencies/PlatformDetectors/LinuxPlatformDetector.cs`
around lines 95 - 121, The InstallUv method blocks the main thread and doesn't
handle WaitForExit timeouts safely; update InstallUv to run asynchronously or be
invoked from a background thread (e.g., Task.Run) so editor UI isn't blocked,
and change its process-wait logic to check the boolean result of
process.WaitForExit(timeout) before reading process.ExitCode—if WaitForExit
returns false, kill/Dispose the child process (Process.Kill/Close) and return
false, and ensure exceptions are logged with full details in the catch; update
callers (MCPSetupWindow and ServerManagementService) to await or otherwise
offload the async/background InstallUv invocation.
| // Check if uv is installed, and offer to install if missing. | ||
| var detector = DependencyManager.GetCurrentPlatformDetector(); | ||
| var uvStatus = detector.DetectUv(); | ||
| if (!uvStatus.IsAvailable) | ||
| { | ||
| if (EditorUtility.DisplayDialog( | ||
| "uv Package Manager Missing", | ||
| "The 'uv' package manager is required to run the local MCP server, but it was not found in your PATH.\n\n" + | ||
| "Would you like to attempt an automatic installation now?", | ||
| "Install uv", | ||
| "Cancel")) | ||
| { | ||
| if (detector.InstallUv()) | ||
| { | ||
| // Re-check after installation | ||
| uvStatus = detector.DetectUv(); | ||
| if (!uvStatus.IsAvailable) | ||
| { | ||
| EditorUtility.DisplayDialog( | ||
| "Installation Incomplete", | ||
| "uv was installed, but it is not yet detected in the current process PATH. " + | ||
| "You may need to restart Unity for the changes to take effect.", | ||
| "OK"); | ||
| return false; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| EditorUtility.DisplayDialog( | ||
| "Installation Failed", | ||
| "Failed to automatically install uv. Please install it manually:\n\n" + detector.GetUvInstallUrl(), | ||
| "OK"); | ||
| return false; | ||
| } | ||
| } | ||
| else | ||
| { | ||
| return false; | ||
| } | ||
| } |
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.
Blocking main thread during uv installation may freeze Unity Editor.
The InstallUv() method (in platform detectors) calls process.WaitForExit(60000), which blocks for up to 60 seconds. This runs on the Unity main thread and will freeze the Editor UI during installation.
Consider running the installation asynchronously or showing a progress dialog to inform the user that the operation is in progress.
💡 Suggested approach
Option 1: Add a simple progress indicator before blocking:
EditorUtility.DisplayProgressBar("Installing uv", "Please wait while uv is being installed...", 0.5f);
try
{
if (detector.InstallUv())
{
// ...
}
}
finally
{
EditorUtility.ClearProgressBar();
}Option 2 (better UX): Refactor InstallUv() to be async and use EditorApplication.update callbacks to poll completion.
🤖 Prompt for AI Agents
In `@MCPForUnity/Editor/Services/ServerManagementService.cs` around lines 414 -
453, The current call to detector.InstallUv() in the ServerManagementService
flow blocks the Unity main thread (via process.WaitForExit), so wrap the
installation with a user-visible progress indicator and ensure the progress bar
is cleared regardless of outcome: before calling InstallUv() show
EditorUtility.DisplayProgressBar("Installing uv", "Please wait while uv is being
installed...", 0.5f), call detector.InstallUv(), then always call
EditorUtility.ClearProgressBar() in a finally block, and only after successful
return call DetectUv() again; alternatively refactor InstallUv() on the platform
detector to an async/polled API and drive it via EditorApplication.update
instead of calling InstallUv() synchronously so the UI remains responsive.
| private void OnAutoInstallUvClicked() | ||
| { | ||
| var detector = DependencyManager.GetCurrentPlatformDetector(); | ||
| if (detector.InstallUv()) | ||
| { | ||
| _dependencyResult = DependencyManager.CheckAllDependencies(); | ||
| UpdateUI(); | ||
|
|
||
| var uvDep = _dependencyResult.Dependencies.Find(d => d.Name == "uv Package Manager"); | ||
| if (uvDep != null && !uvDep.IsAvailable) | ||
| { | ||
| EditorUtility.DisplayDialog( | ||
| "Installation Incomplete", | ||
| "uv was installed, but it is not yet detected in the current process PATH. " + | ||
| "You may need to restart Unity for the changes to take effect.", | ||
| "OK"); | ||
| } | ||
| else | ||
| { | ||
| EditorUtility.DisplayDialog( | ||
| "Installation Successful", | ||
| "uv package manager has been installed successfully.", | ||
| "OK"); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| EditorUtility.DisplayDialog( | ||
| "Installation Failed", | ||
| "Failed to automatically install uv. Please install it manually.", | ||
| "OK"); | ||
| } | ||
| } |
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.
Same blocking concern applies here.
This handler has the same main-thread blocking issue mentioned in ServerManagementService.cs. The InstallUv() call can block for up to 60 seconds, freezing the Editor UI.
Consider adding a progress bar here as well to provide feedback during the installation:
💡 Suggested fix
private void OnAutoInstallUvClicked()
{
var detector = DependencyManager.GetCurrentPlatformDetector();
+ EditorUtility.DisplayProgressBar("Installing uv", "Please wait while uv is being installed...", 0.5f);
+ bool installResult;
+ try
+ {
+ installResult = detector.InstallUv();
+ }
+ finally
+ {
+ EditorUtility.ClearProgressBar();
+ }
+
- if (detector.InstallUv())
+ if (installResult)
{
_dependencyResult = DependencyManager.CheckAllDependencies();
UpdateUI();
// ... rest of the logic📝 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.
| private void OnAutoInstallUvClicked() | |
| { | |
| var detector = DependencyManager.GetCurrentPlatformDetector(); | |
| if (detector.InstallUv()) | |
| { | |
| _dependencyResult = DependencyManager.CheckAllDependencies(); | |
| UpdateUI(); | |
| var uvDep = _dependencyResult.Dependencies.Find(d => d.Name == "uv Package Manager"); | |
| if (uvDep != null && !uvDep.IsAvailable) | |
| { | |
| EditorUtility.DisplayDialog( | |
| "Installation Incomplete", | |
| "uv was installed, but it is not yet detected in the current process PATH. " + | |
| "You may need to restart Unity for the changes to take effect.", | |
| "OK"); | |
| } | |
| else | |
| { | |
| EditorUtility.DisplayDialog( | |
| "Installation Successful", | |
| "uv package manager has been installed successfully.", | |
| "OK"); | |
| } | |
| } | |
| else | |
| { | |
| EditorUtility.DisplayDialog( | |
| "Installation Failed", | |
| "Failed to automatically install uv. Please install it manually.", | |
| "OK"); | |
| } | |
| } | |
| private void OnAutoInstallUvClicked() | |
| { | |
| var detector = DependencyManager.GetCurrentPlatformDetector(); | |
| EditorUtility.DisplayProgressBar("Installing uv", "Please wait while uv is being installed...", 0.5f); | |
| bool installResult; | |
| try | |
| { | |
| installResult = detector.InstallUv(); | |
| } | |
| finally | |
| { | |
| EditorUtility.ClearProgressBar(); | |
| } | |
| if (installResult) | |
| { | |
| _dependencyResult = DependencyManager.CheckAllDependencies(); | |
| UpdateUI(); | |
| var uvDep = _dependencyResult.Dependencies.Find(d => d.Name == "uv Package Manager"); | |
| if (uvDep != null && !uvDep.IsAvailable) | |
| { | |
| EditorUtility.DisplayDialog( | |
| "Installation Incomplete", | |
| "uv was installed, but it is not yet detected in the current process PATH. " + | |
| "You may need to restart Unity for the changes to take effect.", | |
| "OK"); | |
| } | |
| else | |
| { | |
| EditorUtility.DisplayDialog( | |
| "Installation Successful", | |
| "uv package manager has been installed successfully.", | |
| "OK"); | |
| } | |
| } | |
| else | |
| { | |
| EditorUtility.DisplayDialog( | |
| "Installation Failed", | |
| "Failed to automatically install uv. Please install it manually.", | |
| "OK"); | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs` around lines 119 - 151,
OnAutoInstallUvClicked currently calls
DependencyManager.GetCurrentPlatformDetector().InstallUv() on the main thread
which can block the Unity Editor; change this to run the long-running
InstallUv() off the main thread (e.g. Task.Run or a background thread) while
showing EditorUtility.DisplayProgressBar and allowing cancelation, then marshal
back to the main thread to set _dependencyResult =
DependencyManager.CheckAllDependencies(), call UpdateUI(), clear the progress
bar, and show the appropriate EditorUtility.DisplayDialog results; ensure you
reference the existing symbols OnAutoInstallUvClicked,
DependencyManager.GetCurrentPlatformDetector(), InstallUv(), _dependencyResult,
DependencyManager.CheckAllDependencies(), UpdateUI(), and
EditorUtility.DisplayProgressBar/DisplayDialog when implementing the
async/background flow and main-thread UI updates.
|
Hi @dsarno! I’ve opened this PR — let me know if anything needs adjustment. Thanks! |
Description
This PR introduces automatic installation for the
uvpackage manager and enhances the overall dependency management experience. Previously, users had to manually installuvvia external terminals, which often led to "command not found" errors during the first run.Key Changes
🛠 Automatic Installation
Added
InstallUv()support across all platforms:curl🖥 Setup Window Improvements
MCP SetupwindowMCPSetupWindow.ussto ensure consistent button sizing and better layout alignment (vertical column layout for install links)🚀 Smart Startup Flow
ServerManagementServicenow proactively checks foruvbefore launching the local server🔍 Path Resolution Fix
PathResolverServicewhere it would return"uvx"instead ofnullwhen the binary was not foundBenefits
'uvx' is not recognizedshell errorSummary by Sourcery
Add automatic uv installation support and integrate dependency checks into the local server startup and setup UI to streamline MCP configuration.
New Features:
Bug Fixes:
Enhancements:
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.