/* +------------------------------------------------------------------+ | Author: Ivan Murzak (https://github.com/IvanMurzak) | | Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) | | Copyright (c) 2025 Ivan Murzak | | Licensed under the Apache License, Version 2.0. | | See the LICENSE file in the project root for more information. | +------------------------------------------------------------------+ */ #nullable enable namespace com.IvanMurzak.Unity.MCP.Editor.DependencyResolver { /// /// Configuration for the NuGet dependency resolver. /// Contains the list of required NuGet packages and path settings. /// static class NuGetConfig { /// Log tag shared across all DependencyResolver classes. public const string LogTag = "[NuGet]"; /// /// Scripting define added to all build target groups once the resolver /// confirms the NuGet DLLs are in place. Main plugin asmdefs are gated /// on this define so they only attempt to compile when the references /// are guaranteed to resolve. /// public const string ReadyDefine = "UNITY_MCP_READY"; /// /// NuGet v3 flat container base URL. /// Download URL pattern: {base}/{id}/{version}/{id}.{version}.nupkg /// public const string NuGetBaseUrl = "https://api.nuget.org/v3-flatcontainer"; /// /// Where extracted NuGet DLLs are installed (mutable location inside Unity's asset pipeline). /// PluginImporter requires files to be under Assets/ to work. /// public const string InstallPath = "Assets/Plugins/NuGet"; /// /// Where downloaded .nupkg files are cached. /// Library/ survives domain reloads but is not tracked by git. /// public const string CachePath = "Library/NuGetCache"; /// /// Top-level NuGet package dependencies. /// Transitive dependencies are resolved automatically from .nuspec metadata. /// /// includeInBuild: true = DLL included in game builds (runtime dependency) /// includeInBuild: false = editor-only DLL (excluded from builds) /// public static readonly NuGetPackage[] Packages = { // --- Runtime dependencies (included in game builds) --- // v8 pinned to match what McpPlugin.dll (netstandard2.1) is compiled against. // Higher versions cause MissingMethodException at runtime in Unity versions // whose built-in BCL doesn't override our NuGet install (e.g. Unity 6.5). // 6.1.0 drops the unused ModelContextProtocol dep; earlier versions drag in a // v10 BCL stack via MCP.Core.1.2.0 that collides with our v8 pins in Unity. // 6.1.1 bumps the transitive ReflectorNet dependency to 5.1.1. new NuGetPackage("com.IvanMurzak.McpPlugin", "6.7.0", includeInBuild: true), // Pinned explicitly so the resolver doesn't drift below the version // bundled in this package. The atomic API surface (TryModifyAt, // TryPatch, TryReadAt, View, Grep) introduced in 5.1.0 is exercised // by the EditMode tests under Tests/Editor/AtomicApi/, which // compile-fail against 5.0.0. 5.1.1 adds defensive try/catch around // reflection so the documented no-throw contract on Try* methods holds. new NuGetPackage("com.IvanMurzak.ReflectorNet", "5.3.1", includeInBuild: true), new NuGetPackage("System.Text.Json", "8.0.5", includeInBuild: true), new NuGetPackage("Microsoft.AspNetCore.SignalR.Client", "8.0.15", includeInBuild: true), new NuGetPackage("Microsoft.AspNetCore.SignalR.Protocols.Json", "8.0.15", includeInBuild: true), new NuGetPackage("Microsoft.Extensions.Logging", "8.0.1", includeInBuild: true), // Pinned to 8.0.3 to match the transitive requirement from // Microsoft.AspNetCore.Http.Connections.Client 8.0.15 (pulled in via // SignalR.Client 8.0.15 → SignalR.Client.Core 8.0.15). Any lower pin // (e.g. 8.0.2) produces an infinite restore loop on every domain reload: // higher-version-wins extracts 8.0.3 to disk while AllPackagesInstalled() // keeps checking for the pinned dir, never finds it, and triggers Restore() // again on the next reload. See Unity-MCP#677. new NuGetPackage("Microsoft.Extensions.Logging.Abstractions", "8.0.3", includeInBuild: true), new NuGetPackage("Microsoft.Extensions.DependencyInjection", "8.0.1", includeInBuild: true), new NuGetPackage("Microsoft.Extensions.DependencyInjection.Abstractions", "8.0.2", includeInBuild: true), new NuGetPackage("Microsoft.Extensions.Options", "8.0.2", includeInBuild: true), new NuGetPackage("Microsoft.Extensions.Caching.Abstractions", "8.0.0", includeInBuild: true), new NuGetPackage("Microsoft.Extensions.Hosting.Abstractions", "8.0.1", includeInBuild: true), new NuGetPackage("R3", "1.3.0", includeInBuild: true), // --- Editor-only dependencies (excluded from builds) --- new NuGetPackage("Microsoft.Bcl.Memory", "10.0.3"), // Pinned to 4.8.0 so transitive System.Collections.Immutable stays at 7.0.0 // (forward-compatible with Unity 6.6's built-in 8.0.0). Roslyn 4.14 requires // SCI 9.0.0 which clashes with Unity's built-in. new NuGetPackage("Microsoft.CodeAnalysis.CSharp", "4.8.0"), }; /// /// Package IDs to exclude from transitive dependency resolution. Matched /// case-insensitively against the NuGet package ID (not the DLL filename). /// /// When a package ID appears here: /// - the resolver skips it (and its transitive deps) during Install() /// - RemoveUnnecessaryPackages() deletes its install directory if present /// - AllPackagesInstalled() forces a full restore while it's still on disk /// /// Use this when a top-level package's nuspec pulls in a transitive dep that /// is unused by your project's source AND whose own dependency chain conflicts /// with your pinned versions (e.g., a netstandard2.0 package targeting a newer /// BCL than Unity's runtime provides). /// public static readonly string[] SkipPackages = { }; /// /// Target framework priority for selecting DLLs from .nupkg lib/ folders. /// First match wins. Ordered by preference for Unity compatibility. /// public static readonly string[] TargetFrameworkPriority = { "netstandard2.1", "netstandard2.0", "net48", "net472", "net471", "net47", "net462", "net461", "net46", "net45", "netstandard1.3", "netstandard1.1", "netstandard1.0", "", // fallback: root lib/ folder }; } }