Skip to content

feat(editor): embed Ocean brand mark in Editor UI + setup polish#1231

Merged
Scriptwonder merged 4 commits into
CoplayDev:betafrom
Scriptwonder:feat/editor-logo-setup-polish
Jul 4, 2026
Merged

feat(editor): embed Ocean brand mark in Editor UI + setup polish#1231
Scriptwonder merged 4 commits into
CoplayDev:betafrom
Scriptwonder:feat/editor-logo-setup-polish

Conversation

@Scriptwonder

@Scriptwonder Scriptwonder commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

What

Brings the Ocean split-cube brand mark into the Editor UI (it previously lived only in the website/README) and lands three low-risk installation-flow improvements.

Logo

  • OceanMark — a reusable UI Toolkit control that draws the mark in Painter2D vector (geometry transcribed directly from website/static/img/logo-mark.svg, brand colors baked in). Crisp at any DPI, theme-independent, no new package dependency.
  • Version handling: Painter2D is Unity 2022.1+ only. The drawing is guarded by #if UNITY_2022_1_OR_NEWER; on the 2021.3 floor the control falls back to the raster package-icon.png. Vector on modern editors, still-branded on the floor.
  • Embedded in the main window header (wrapped title in a #header-left group so the version pill stays right-aligned) and the setup-wizard header.
  • package-icon.png now ships inside the package (canonical listing/Asset-Store icon + doubles as the 2021.3 fallback). Note: Unity's in-editor Package Manager can't render custom icons for git packages, so this is for listings/fallback, not the PM tile.

Installation polish

  • One-click uv installUvInstaller builds the official installer command per platform (astral.sh/uv/install.sh | install.ps1); the setup wizard runs it off the main thread behind a confirm dialog, then re-checks dependencies. Manual "Open UV Install Page" link stays as fallback.
  • Claude CLI auto-discovery — consolidated the weaker duplicate resolver in PathResolverService.GetClaudeCliPath() into the fuller ExecPath.ResolveClaude() (−~50 lines), and added ~/.claude/local/claude (the claude migrate-installer location both resolvers missed). IsClaudeCliDetected() now gets NVM + PATH-scan for free, on all platforms.
  • Setup wizard clarity — a real next-step line on success ("ask your AI assistant to create a GameObject to confirm the connection").

Tests

EditMode coverage added: geometry/color mapping (OceanMarkTests), per-platform uv command construction (UvInstallerTests), and the Claude override contract (PathResolverClaudeCliTests).

Verification

  • ✅ Compiles clean on 2021.3.45f2 (raster fallback + all unguarded code + tests)
  • ✅ Compiles clean on 6000.4.11f1 (Painter2D path) — 0 error CS
  • ✅ Adversarial multi-agent review: 1 minor bug found (stale status label after failed install) and fixed; false positives rejected

Not covered here

  • Visual eyeball of the rendered mark in a running Editor (compiled both paths; haven't rendered pixels) — reviewers may want to sanity-check header sizing/USS.
  • CI covers the 2022.3 and 6000.0 matrix rows I don't have installed locally.

Summary by CodeRabbit

  • New Features
    • Added one-click automatic UV installation in the setup window with in-progress handling and improved success/failure dialogs.
    • Introduced a new branded OceanMark logo in the editor header.
  • Bug Fixes
    • Improved Claude CLI detection with extra install-location fallback.
    • Made invalid Claude CLI path overrides strictly fail without auto-discovery.
    • Refined header/connection layout so elements wrap and buttons don’t overlap or clip on narrow windows.
  • Tests
    • Added EditMode tests covering Claude CLI override behavior and UV installer command generation.

Add the Ocean split-cube brand mark to the Editor UI and land three
low-risk installation-flow improvements.

Logo:
- OceanMark: reusable UI Toolkit control drawing the mark in Painter2D
  vector (geometry transcribed from logo-mark.svg, brand colors baked in),
  crisp at any DPI with no new package dependency. Painter2D is 2022.1+,
  so it is guarded by #if UNITY_2022_1_OR_NEWER with a raster fallback
  (package-icon.png) on the 2021.3 floor.
- Embedded in the main window header (#header-left group) and the
  setup-wizard header.
- Ship package-icon.png inside the package (listing icon + 2021.3 fallback).

Installation polish:
- One-click uv install: UvInstaller builds the official installer command
  per platform; setup wizard runs it off-thread with a confirm dialog and
  re-checks dependencies.
- Claude CLI auto-discovery: consolidate the weaker resolver into
  ExecPath.ResolveClaude() and add the ~/.claude/local (migrate-installer)
  location both resolvers missed.
- Setup wizard clarity: success/next-step copy after configuring clients.

Tests: EditMode coverage for the geometry/color mapping, per-platform uv
command, and the Claude override contract.

Verified: compiles clean on 2021.3.45f2 (fallback path) and 6000.4.11f1
(Painter2D path).
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a UvInstaller utility and setup-window install flow, introduces an OceanMark branding element used in editor windows, extends Claude CLI resolution with a shared fallback path, and adds matching tests and Unity metadata.

Changes

UV install flow, branding, and Claude CLI resolution

Layer / File(s) Summary
UvInstaller command building and execution
MCPForUnity/Editor/Dependencies/UvInstaller.cs, ...UvInstaller.cs.meta, TestProjects/.../UvInstallerTests.cs*
New UvInstaller static class builds OS-specific install commands, describes and executes them via ExecPath.TryRun, returning a structured UvInstallResult; tests validate platform-specific command shape, description text, and support detection.
MCPSetupWindow UV install UI wiring and dialog updates
MCPForUnity/Editor/Windows/MCPSetupWindow.cs, MCPSetupWindow.uss, MCPSetupWindow.uxml
Adds an "Install UV Automatically" button, background task tracking (_uvInstallTask), completion polling via EditorApplication.update, updated button visibility logic, revised client-configuration dialog messaging (failures-only), and header/button layout styling.
OceanMark branding visual element
MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs*, Branding.meta, MCPForUnity/package-icon.png.meta
New decorative VisualElement renders a vector "Ocean split-cube" mark on Unity 2022.1+ via Painter2D, falling back to a raster package-icon.png on older versions, with SVG-to-rect mapping and hex color helpers.
Branding integration into editor windows
MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs, MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss, MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml, MCPForUnity/Editor/Windows/Components/Common.uss
Injects OceanMark into the main editor window header, restructures header markup with a header-left container, and adjusts header/toolbar/connection-status styling.
Claude CLI resolution fallback path
MCPForUnity/Editor/Helpers/ExecPath.cs, MCPForUnity/Editor/Services/PathResolverService.cs, TestProjects/.../PathResolverClaudeCliTests.cs*
ExecPath.ResolveClaude() adds a ~/.claude/local/claude(.exe) fallback candidate; PathResolverService.GetClaudeCliPath() now delegates non-override discovery to ExecPath.ResolveClaude(); tests cover valid/invalid override behavior.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant MCPSetupWindow
  participant UvInstaller
  participant ExecPath
  participant EditorApplication

  User->>MCPSetupWindow: Click "Install UV Automatically"
  MCPSetupWindow->>MCPSetupWindow: Confirm and disable button
  MCPSetupWindow->>UvInstaller: Run() (background Task)
  UvInstaller->>UvInstaller: BuildInstallCommand()
  UvInstaller->>ExecPath: TryRun(file, arguments)
  ExecPath-->>UvInstaller: stdout / stderr
  UvInstaller-->>MCPSetupWindow: UvInstallResult
  MCPSetupWindow->>EditorApplication: Subscribe PollUvInstall to update
  loop Until task completes
    EditorApplication->>MCPSetupWindow: update tick
    MCPSetupWindow->>MCPSetupWindow: Check _uvInstallTask.IsCompleted
  end
  MCPSetupWindow->>MCPSetupWindow: Re-enable button, refresh dependency checks
  MCPSetupWindow-->>User: Show success/PATH guidance or failure dialog
Loading

Possibly related PRs

  • CoplayDev/unity-mcp#209: Both PRs modify ExecPath.ResolveClaude()’s Claude CLI path resolution logic, so the shared fallback path change is directly related.
  • Suggested reviewers: msanatan, dsarno
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main editor branding and setup changes.
Description check ✅ Passed The description is detailed and covers the main changes, tests, verification, and notes, though it doesn’t follow the exact template headings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Scriptwonder Scriptwonder added the enhancement New feature or request label Jul 3, 2026
- Setup wizard: de-box the title beside the logo; footer buttons size to
  content and sit together on one row (Refresh no longer stretches
  full-width and overflows); rename the deps-step "Done" button to "Next".
- Client Configuration dialog: show the count + only failures + next step
  instead of enumerating every successfully configured client.
- Main window header: version pill never shrinks/clips (flex-shrink 0);
  title stays at natural width.
- Tabs: flex-shrink so all six stay reachable when docked narrow.
- Connection status label wraps/shrinks instead of sliding under the
  Disconnect button (scoped to #connection-section).
@Scriptwonder Scriptwonder marked this pull request as ready for review July 3, 2026 18:19
Copilot AI review requested due to automatic review settings July 3, 2026 18:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR brings the Ocean split-cube brand mark into the Unity Editor UI (vector via UI Toolkit Painter2D on 2022.1+, raster fallback on 2021.3) and adds several setup-flow improvements around dependency installation and CLI discovery.

Changes:

  • Add OceanMark UI Toolkit control and embed it into the main window header and setup wizard header (with 2021.3 raster fallback).
  • Add one-click uv installation via a new UvInstaller helper and wire it into the setup wizard UI/UX.
  • Consolidate Claude CLI discovery to ExecPath.ResolveClaude() (including ~/.claude/local/*) and add EditMode coverage for the new behaviors.

Reviewed changes

Copilot reviewed 14 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs.meta Adds Unity meta for new EditMode test.
TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs Tests platform-specific uv installer command construction and supported platforms.
TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs.meta Adds Unity meta for new EditMode test.
TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs Tests Claude CLI override contract (valid override honored; invalid override returns null without fallback).
TestProjects/UnityMCPTests/Assets/Tests/EditMode/OceanMarkTests.cs.meta Adds Unity meta for new EditMode test.
TestProjects/UnityMCPTests/Assets/Tests/EditMode/OceanMarkTests.cs Tests OceanMark color parsing and SVG-to-rect mapping helpers.
MCPForUnity/package-icon.png.meta Adds import settings/meta for the raster fallback/package icon.
MCPForUnity/Editor/Windows/MCPSetupWindow.uxml Adds a header container for logo injection and a new “Install UV Automatically” button; renames Done → Next.
MCPForUnity/Editor/Windows/MCPSetupWindow.uss Styles setup header/logo and improves footer button layout/wrapping.
MCPForUnity/Editor/Windows/MCPSetupWindow.cs Injects the logo, adds uv auto-install flow, and improves client configuration summary messaging.
MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml Wraps header title into a left group for logo injection while keeping version right-aligned.
MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss Styles header-left/logo and tweaks header/version/tab toolbar layout behavior.
MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs Injects OceanMark into the main editor window header.
MCPForUnity/Editor/Windows/Components/Common.uss Improves connection status row behavior at narrow widths (wrapping/shrinking).
MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs.meta Adds Unity meta for new branding component.
MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs Implements the vector OceanMark (Painter2D on 2022.1+) with 2021.3 raster fallback + mapping helpers.
MCPForUnity/Editor/Windows/Components/Branding.meta Adds folder meta for new Branding component folder.
MCPForUnity/Editor/Services/PathResolverService.cs Delegates Claude auto-discovery to ExecPath.ResolveClaude() when no override is set.
MCPForUnity/Editor/Helpers/ExecPath.cs Adds ~/.claude/local/claude(.exe) candidate paths for Claude CLI resolution.
MCPForUnity/Editor/Dependencies/UvInstaller.cs.meta Adds Unity meta for new dependency helper.
MCPForUnity/Editor/Dependencies/UvInstaller.cs Adds a testable uv installer command builder + runner with truncated output for dialogs.
Files not reviewed (7)
  • MCPForUnity/Editor/Dependencies/UvInstaller.cs.meta: Generated file
  • MCPForUnity/Editor/Windows/Components/Branding.meta: Generated file
  • MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs.meta: Generated file
  • MCPForUnity/package-icon.png.meta: Generated file
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/OceanMarkTests.cs.meta: Generated file
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs.meta: Generated file
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs.meta: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +293 to +296
private void OnDisable()
{
EditorApplication.update -= PollUvInstall;
}
Comment on lines +254 to +264
private void PollUvInstall()
{
if (_uvInstallTask == null || !_uvInstallTask.IsCompleted) return;

EditorApplication.update -= PollUvInstall;
var task = _uvInstallTask;
_uvInstallTask = null;

installUvButton.SetEnabled(true);
installUvButton.text = "Install UV Automatically";

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
MCPForUnity/Editor/Windows/MCPSetupWindow.cs (1)

96-96: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Inconsistent defensive null-checks around a guaranteed UI element.

installUvButton is unconditionally defined in the UXML, yet it's null-checked before wiring the click handler (Line 110) and before toggling visibility (Line 319), while sibling buttons (refreshButton, doneButton) are used unconditionally right below. If the UXML name ever drifts from install-uv-button, this pattern silently disables the whole install feature instead of surfacing a clear failure.

Based on learnings, "prefer relying on the established testing process to catch UI initialization issues instead of adding defensive null checks for UI elements in editor windows... unless a well-tested fallback or that its initialization is guaranteed by design."

♻️ Proposed consistency fix
-            if (installUvButton != null) installUvButton.clicked += OnInstallUvClicked;
+            installUvButton.clicked += OnInstallUvClicked;
-            if (installUvButton != null)
-            {
-                bool showInstall = uvMissing && UvInstaller.IsSupported && _uvInstallTask == null;
-                installUvButton.style.display = showInstall ? DisplayStyle.Flex : DisplayStyle.None;
-            }
+            bool showInstall = uvMissing && UvInstaller.IsSupported && _uvInstallTask == null;
+            installUvButton.style.display = showInstall ? DisplayStyle.Flex : DisplayStyle.None;

Also applies to: 110-110, 317-324

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs` at line 96, Remove the
inconsistent null-guarding around the guaranteed install UV UI element in
MCPSetupWindow. In the window initialization and visibility code that uses
installUvButton, follow the same pattern as refreshButton and doneButton: assume
the UXML binding is correct and wire the click handler / toggle visibility
directly, letting any mismatch surface during setup or tests instead of silently
disabling the install flow.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs`:
- Around line 26-33: The Painter2D vs. raster-fallback version branching in
OceanMark should be moved out of the constructor and call sites into a compat
shim. Extract the “does Painter2D support exist” and render-strategy selection
logic into a UnityPainter2DCompat helper under Runtime/Helpers, then have
OceanMark use that helper instead of inline UNITY_2022_1_OR_NEWER checks. Update
the related render setup paths in OceanMark so they rely on the shim for
behavior selection rather than embedding preprocessor directives directly.
- Around line 129-140: The LoadBrandTexture method is swallowing all exceptions,
which hides asset-loading failures on the 2021.3 fallback path. Update the
try/catch in LoadBrandTexture to catch the failure, log a clear error with the
exception details and the package root/path context, and then return null; keep
the behavior of returning null on failure, but make the failure visible instead
of silent.

In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs`:
- Around line 232-297: The uv install guard is only stored on the MCPSetupWindow
instance, so closing and reopening the window can start another UvInstaller.Run
while the first is still active. Move the in-flight install tracking out of the
window instance or into a shared/static guard used by OnInstallUvClicked and
PollUvInstall, and make OnDisable prevent the window from being closed or
otherwise preserve the running task state until completion.

---

Nitpick comments:
In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs`:
- Line 96: Remove the inconsistent null-guarding around the guaranteed install
UV UI element in MCPSetupWindow. In the window initialization and visibility
code that uses installUvButton, follow the same pattern as refreshButton and
doneButton: assume the UXML binding is correct and wire the click handler /
toggle visibility directly, letting any mismatch surface during setup or tests
instead of silently disabling the install flow.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2705c3fe-aa9f-4b70-ac3c-6e0e95c8a318

📥 Commits

Reviewing files that changed from the base of the PR and between 8618f83 and 3e36002.

⛔ Files ignored due to path filters (1)
  • MCPForUnity/package-icon.png is excluded by !**/*.png
📒 Files selected for processing (21)
  • MCPForUnity/Editor/Dependencies/UvInstaller.cs
  • MCPForUnity/Editor/Dependencies/UvInstaller.cs.meta
  • MCPForUnity/Editor/Helpers/ExecPath.cs
  • MCPForUnity/Editor/Services/PathResolverService.cs
  • MCPForUnity/Editor/Windows/Components/Branding.meta
  • MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs
  • MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs.meta
  • MCPForUnity/Editor/Windows/Components/Common.uss
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml
  • MCPForUnity/Editor/Windows/MCPSetupWindow.cs
  • MCPForUnity/Editor/Windows/MCPSetupWindow.uss
  • MCPForUnity/Editor/Windows/MCPSetupWindow.uxml
  • MCPForUnity/package-icon.png.meta
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/OceanMarkTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/OceanMarkTests.cs.meta
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs.meta
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs.meta

Comment thread MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs
Comment thread MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs
Comment on lines +232 to +297
private void OnInstallUvClicked()
{
if (_uvInstallTask != null) return; // already running

bool proceed = EditorUtility.DisplayDialog(
"Install UV",
"This will download and run the official uv installer:\n\n" +
UvInstaller.DescribeCommand() +
"\n\nContinue?",
"Install",
"Cancel");
if (!proceed) return;

installUvButton.SetEnabled(false);
installUvButton.text = "Installing UV…";
statusMessage.text = "Installing uv… this can take a moment.";
statusMessage.style.color = new StyleColor(new Color(1f, 0.6f, 0f));

_uvInstallTask = Task.Run(() => UvInstaller.Run());
EditorApplication.update += PollUvInstall;
}

private void PollUvInstall()
{
if (_uvInstallTask == null || !_uvInstallTask.IsCompleted) return;

EditorApplication.update -= PollUvInstall;
var task = _uvInstallTask;
_uvInstallTask = null;

installUvButton.SetEnabled(true);
installUvButton.text = "Install UV Automatically";

// UvInstaller.Run catches its own exceptions, so the task always completes with a result.
UvInstaller.UvInstallResult result = task.Result;

if (result.Success)
{
_dependencyResult = DependencyManager.CheckAllDependencies();
UpdateUI();
if (!_dependencyResult.IsSystemReady)
{
EditorUtility.DisplayDialog(
"Install UV",
"uv installed, but it isn't visible on PATH yet. Restart Unity (or your terminal) so it picks up the new PATH, then click Refresh.\n\n" +
result.Output,
"OK");
}
}
else
{
// Reset the status label off the "Installing…" state before reporting the failure.
UpdateUI();
EditorUtility.DisplayDialog(
"Install UV Failed",
"The installer did not complete successfully. You can install uv manually via \"Open UV Install Page\".\n\n" +
result.Output,
"OK");
}
}

private void OnDisable()
{
EditorApplication.update -= PollUvInstall;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- MCPSetupWindow.cs outline ---\n'
ast-grep outline MCPForUnity/Editor/Windows/MCPSetupWindow.cs --view expanded || true

printf '\n--- UvInstaller references ---\n'
rg -n "class UvInstaller|Run\(|DescribeCommand|UvInstallResult|SessionState|static .*install|install in progress|PollUvInstall|OnDisable|OnEnable" MCPForUnity -S

printf '\n--- MCPSetupWindow.cs relevant slice ---\n'
nl -ba MCPForUnity/Editor/Windows/MCPSetupWindow.cs | sed -n '1,360p'

printf '\n--- UvInstaller source candidates ---\n'
fd -a "UvInstaller.cs|*UvInstaller*.cs" MCPForUnity

Repository: CoplayDev/unity-mcp

Length of output: 248


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- MCPSetupWindow.cs outline ---'
ast-grep outline MCPForUnity/Editor/Windows/MCPSetupWindow.cs --view expanded || true

echo
echo '--- UvInstaller references ---'
rg -n "class UvInstaller|Run\(|DescribeCommand|UvInstallResult|SessionState|static .*install|install in progress|PollUvInstall|OnDisable|OnEnable" MCPForUnity -S

echo
echo '--- MCPSetupWindow.cs relevant slice ---'
nl -ba MCPForUnity/Editor/Windows/MCPSetupWindow.cs | sed -n '1,360p'

echo
echo '--- UvInstaller source candidates ---'
fd -a "UvInstaller.cs|*UvInstaller*.cs" MCPForUnity

Repository: CoplayDev/unity-mcp

Length of output: 21099


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- MCPSetupWindow.cs (selected ranges) ---'
sed -n '1,220p' MCPForUnity/Editor/Windows/MCPSetupWindow.cs | cat -n
echo
sed -n '220,340p' MCPForUnity/Editor/Windows/MCPSetupWindow.cs | cat -n

echo
echo '--- UvInstaller.cs ---'
sed -n '1,220p' MCPForUnity/Editor/Dependencies/UvInstaller.cs | cat -n

echo
echo '--- SetupWindowService.cs ---'
sed -n '1,120p' MCPForUnity/Editor/Setup/SetupWindowService.cs | cat -n

Repository: CoplayDev/unity-mcp

Length of output: 25231


Prevent duplicate uv installs across window reopen. _uvInstallTask is scoped to the current EditorWindow, so closing the window drops the guard while the installer keeps running. Reopening the setup window can start a second UvInstaller.Run() against the same target. Track the in-flight install outside the window instance, or block closing until it finishes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs` around lines 232 - 297, The uv
install guard is only stored on the MCPSetupWindow instance, so closing and
reopening the window can start another UvInstaller.Run while the first is still
active. Move the in-flight install tracking out of the window instance or into a
shared/static guard used by OnInstallUvClicked and PollUvInstall, and make
OnDisable prevent the window from being closed or otherwise preserve the running
task state until completion.

…ilure

Addresses AI review (Copilot + CodeRabbit) on CoplayDev#1231:
- PollUvInstall: bail out (and detach) if the window/UI was torn down while
  the task ran, guarding against dereferencing UI fields after teardown.
- OnEnable: resume polling if an install was still in flight when the window
  was disabled, so completion is still processed (button reset, deps re-checked).
- OceanMark.LoadBrandTexture: log a warning instead of silently swallowing
  asset-load failures on the 2021.3 raster-fallback path.

Declined CodeRabbit's "use a compat shim" suggestion for OceanMark's
#if UNITY_2022_1_OR_NEWER: per UnityCompatShims.cs policy, shims are for
[Obsolete] APIs, 3+ gated call sites, or announced removals — Painter2D is a
new API used via static dispatch in one self-contained file, which the policy
explicitly says to handle with #if, not a shim.
@Scriptwonder

Copy link
Copy Markdown
Collaborator Author

AI review addressed in c46d86d:

  • uv-install lifecycle (Copilot ×2, CodeRabbit): PollUvInstall now bails out + detaches if the window/UI was torn down mid-install; OnEnable resumes polling if an install was still in flight when the window was disabled, so completion is still processed.
  • Silent fallback failure (CodeRabbit): OceanMark.LoadBrandTexture now logs via McpLog.Warn instead of swallowing asset-load errors.
  • ⏸️ Compat shim for OceanMark's #if (CodeRabbit, Major): respectfully declined — see the inline thread. The shim policy explicitly prefers #if for new-API static dispatch in a single self-contained site.

Note: the fallback-logging change is in the #else (2021.3) branch, which the default PR CI (6000.0) doesn't compile — it's a trivial McpLog.Warn addition and gets exercised by the full Unity matrix on merge to beta.

…o the #if

- Remove OceanMarkTests (geometry/color mapping + construction) per request;
  the mark is verified visually in-Editor.
- With the test gone, MapSvgPoint/FromHex no longer need to be `internal`,
  and they (plus the SvgOrigin/SvgSize consts) are only used by the Painter2D
  path — move them inside `#if UNITY_2022_1_OR_NEWER` and make them `private`,
  so the 2021.3 fallback carries no unused members.

Result of a /simplify pass; reuse/altitude/efficiency angles came back clean
(logo-injection duplication left at 2 call sites per the repo's 3+-uses rule).
@Scriptwonder

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
MCPForUnity/Editor/Windows/MCPSetupWindow.cs (1)

110-110: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent defensive null check on installUvButton.

install-uv-button is unconditionally present in the uxml (added in this same PR), so this null check is inconsistent with how sibling buttons (refreshButton, doneButton, etc.) are wired without guards.

Based on learnings, prefer relying on the established testing process to catch UI initialization issues instead of adding defensive null checks for UI elements in editor windows, ensuring initialization is guaranteed by design rather than sprinkling null checks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs` at line 110, Remove the
defensive null guard around installUvButton in MCPSetupWindow; the UI element is
guaranteed by the UXML, and sibling controls like refreshButton and doneButton
are wired directly. Update the initialization in the window setup code to match
the existing pattern by attaching OnInstallUvClicked without a null check,
relying on the established UI initialization/testing flow instead of adding
per-element guards.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@MCPForUnity/Editor/Windows/MCPSetupWindow.cs`:
- Line 110: Remove the defensive null guard around installUvButton in
MCPSetupWindow; the UI element is guaranteed by the UXML, and sibling controls
like refreshButton and doneButton are wired directly. Update the initialization
in the window setup code to match the existing pattern by attaching
OnInstallUvClicked without a null check, relying on the established UI
initialization/testing flow instead of adding per-element guards.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b90592ab-fb2a-4690-b915-79ecd87f0d1a

📥 Commits

Reviewing files that changed from the base of the PR and between 8618f83 and 42d9faa.

⛔ Files ignored due to path filters (1)
  • MCPForUnity/package-icon.png is excluded by !**/*.png
📒 Files selected for processing (19)
  • MCPForUnity/Editor/Dependencies/UvInstaller.cs
  • MCPForUnity/Editor/Dependencies/UvInstaller.cs.meta
  • MCPForUnity/Editor/Helpers/ExecPath.cs
  • MCPForUnity/Editor/Services/PathResolverService.cs
  • MCPForUnity/Editor/Windows/Components/Branding.meta
  • MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs
  • MCPForUnity/Editor/Windows/Components/Branding/OceanMark.cs.meta
  • MCPForUnity/Editor/Windows/Components/Common.uss
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uss
  • MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml
  • MCPForUnity/Editor/Windows/MCPSetupWindow.cs
  • MCPForUnity/Editor/Windows/MCPSetupWindow.uss
  • MCPForUnity/Editor/Windows/MCPSetupWindow.uxml
  • MCPForUnity/package-icon.png.meta
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/PathResolverClaudeCliTests.cs.meta
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/UvInstallerTests.cs.meta

@Scriptwonder Scriptwonder merged commit 9e8e675 into CoplayDev:beta Jul 4, 2026
4 checks passed
@Scriptwonder Scriptwonder deleted the feat/editor-logo-setup-polish branch July 4, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants