@atelierai/uco 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -8
- package/package.json +2 -2
- package/vendor/plugin/com.atelierai.unity.copilot/CHANGELOG.md +4 -4
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetConfig.cs +132 -132
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDependencyResolver.cs +237 -237
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDownloader.cs +82 -82
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/MenuItems.cs +247 -247
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/ToolGroups.cs +153 -153
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/SystemTool/Skills.Create.SkillBody.cs +155 -155
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Console.GetLogs.cs +95 -95
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Docs.HttpFetcher.cs +139 -139
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Instance.ListAll.cs +72 -72
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/PathReadHelper.cs +106 -106
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Script.Validate.cs +252 -252
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests/TestResultCollector.cs +537 -537
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests.cs +400 -400
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/ToolGroups.SetEnabled.cs +92 -92
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Branding/ProductInfo.cs +62 -62
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +887 -1034
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Skills/Skill_InitialSetup.cs +197 -197
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.Editor.cs +201 -201
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.cs +67 -67
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotListWindowBase.cs +393 -393
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotWindowBase.cs +113 -113
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.Connection.cs +3 -3
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotFeatures.cs +195 -195
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotServer.cs +22 -22
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CreateGUI.cs +354 -354
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.cs +78 -78
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowInitializer.cs +47 -47
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/SerializationCheckWindow.cs +190 -190
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Build.cs +91 -91
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Config.cs +298 -298
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Static.cs +296 -296
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.cs +69 -69
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PackageUtils.cs +168 -168
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PrefsKeyMigration.cs +119 -119
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/SafeDefaultsGuard.cs +180 -180
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ScriptUtils.cs +229 -229
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolGroupRegistry.cs +461 -460
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolsManifestGenerator.cs +200 -200
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringAdapters.cs +1467 -1467
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringSafetyReloadGuard.cs +65 -65
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityCopilotUpdateProjectSettings.cs +66 -66
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/CopilotPromptsWindow.uss +11 -11
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/CopilotResourcesWindow.uss +16 -16
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/CopilotToolsWindow.uss +36 -36
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/MainWindow.uss +183 -183
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/common/{_mcp-list-window.uss → _copilot-list-window.uss} +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/common/_list-view.uss +77 -77
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/CopilotPromptsWindow.uxml +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/CopilotResourcesWindow.uxml +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/CopilotToolsWindow.uxml +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/MainWindow.uxml +115 -115
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/ReflectorNet.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.Common.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/README.md +88 -88
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Converter/Json/Structures/EntityIdConverter.cs +120 -120
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.cs +110 -110
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.pre-Unity.6.5.cs +110 -110
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/FileLogStorage.cs +547 -547
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Build.cs +243 -243
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Config.cs +3 -3
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.cs +295 -295
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginBuilder.cs +105 -105
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.Static.cs +155 -155
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.cs +59 -59
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Utils/EnvironmentUtils.cs +11 -11
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/AtomicApiTestFixtures.cs +99 -99
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/TryModifyAtTests.cs +227 -227
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AuthoringSafetyPilotTests.cs +1050 -1050
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetExtractorDevelopmentDependencyTests.cs +148 -148
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetExtractorFlatLayoutTests.cs +166 -166
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetInstallManifestTests.cs +436 -436
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetLegacyMigrationTests.cs +304 -304
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetPackageInstallerStaleVersionCleanupTests.cs +200 -200
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +2 -2
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/BlacklistTypeTests.cs +416 -416
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.cs +172 -172
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.pre-Unity.6.5.cs +169 -169
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.cs +182 -182
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.pre-Unity.6.5.cs +179 -179
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.cs +175 -175
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.pre-Unity.6.5.cs +174 -174
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.cs +171 -171
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.pre-Unity.6.5.cs +170 -170
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsCreateFolderTests.cs +243 -243
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsMaterialTests.cs +101 -101
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.cs +348 -348
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.pre-Unity.6.5.cs +348 -348
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsShaderTests.cs +194 -194
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/GameObject/TestJsonSchema.cs +199 -199
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.cs +573 -573
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.pre-Unity.6.5.cs +513 -513
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.cs +154 -154
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.pre-Unity.6.5.cs +154 -154
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotGameViewTests.cs +164 -164
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotSceneViewTests.cs +155 -155
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolParameterTests.cs +56 -56
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.cs +651 -651
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.pre-Unity.6.5.cs +651 -651
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ToolBatchExecutionIntegrationTests.cs +407 -407
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs → UcoPluginTests.cs} +105 -105
- package/vendor/plugin/com.atelierai.unity.copilot/package.json +1 -1
- /package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/common/{_mcp-list-window.uss.meta → _copilot-list-window.uss.meta} +0 -0
- /package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs.meta → UcoPluginTests.cs.meta} +0 -0
package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Static.cs
CHANGED
|
@@ -1,296 +1,296 @@
|
|
|
1
|
-
/*
|
|
2
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
3
|
-
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
4
|
-
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
5
|
-
│ Copyright (c) 2025 Ivan Murzak │
|
|
6
|
-
│ Licensed under the Apache License, Version 2.0. │
|
|
7
|
-
│ See the LICENSE file in the project root for more information. │
|
|
8
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
#nullable enable
|
|
12
|
-
using System;
|
|
13
|
-
using System.Diagnostics.CodeAnalysis;
|
|
14
|
-
using System.IO;
|
|
15
|
-
using System.Runtime.InteropServices;
|
|
16
|
-
using System.Threading;
|
|
17
|
-
using System.Threading.Tasks;
|
|
18
|
-
using com.AtelierAI.Uco.Framework;
|
|
19
|
-
using WsState = com.AtelierAI.Uco.Framework.ConnectionState;
|
|
20
|
-
using com.AtelierAI.Uco.Framework.Common;
|
|
21
|
-
using com.AtelierAI.Uco.Framework.Common.Model;
|
|
22
|
-
using com.AtelierAI.Unity.Copilot.Utils;
|
|
23
|
-
using Microsoft.Extensions.Logging;
|
|
24
|
-
using R3;
|
|
25
|
-
|
|
26
|
-
namespace com.AtelierAI.Unity.Copilot
|
|
27
|
-
{
|
|
28
|
-
using static com.AtelierAI.Uco.Framework.Common.Consts.
|
|
29
|
-
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
|
30
|
-
using LogLevel = com.AtelierAI.Unity.Copilot.Runtime.Utils.LogLevel;
|
|
31
|
-
|
|
32
|
-
public partial class UnityCopilotPluginEditor
|
|
33
|
-
{
|
|
34
|
-
static readonly Subject<UnityConnectionConfig> _onConfigChanged = new Subject<UnityConnectionConfig>();
|
|
35
|
-
static readonly ILogger _logger = UnityLoggerFactory.LoggerFactory.CreateLogger<UnityCopilotPluginEditor>();
|
|
36
|
-
static readonly object _instanceMutex = new();
|
|
37
|
-
|
|
38
|
-
static UnityCopilotPluginEditor instance = null!;
|
|
39
|
-
|
|
40
|
-
public static bool HasInstance
|
|
41
|
-
{
|
|
42
|
-
get
|
|
43
|
-
{
|
|
44
|
-
lock (_instanceMutex)
|
|
45
|
-
{
|
|
46
|
-
return instance != null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
public static UnityCopilotPluginEditor Instance
|
|
51
|
-
{
|
|
52
|
-
get
|
|
53
|
-
{
|
|
54
|
-
InitSingletonIfNeeded();
|
|
55
|
-
lock (_instanceMutex)
|
|
56
|
-
{
|
|
57
|
-
return instance;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
public static void InitSingletonIfNeeded()
|
|
63
|
-
{
|
|
64
|
-
lock (_instanceMutex)
|
|
65
|
-
{
|
|
66
|
-
if (instance == null)
|
|
67
|
-
{
|
|
68
|
-
instance = new UnityCopilotPluginEditor();
|
|
69
|
-
if (instance == null)
|
|
70
|
-
{
|
|
71
|
-
_logger.LogWarning("{method}: UnityCopilotPluginEditor instance is null",
|
|
72
|
-
nameof(InitSingletonIfNeeded));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Replaces UcoFramework.UcoFramework static singleton behavior
|
|
80
|
-
private static readonly ReactiveProperty<IUcoPlugin?> _pluginProperty = new(null);
|
|
81
|
-
public static ReadOnlyReactiveProperty<IUcoPlugin?> PluginProperty => _pluginProperty;
|
|
82
|
-
public static IUcoPlugin? CurrentPlugin => _pluginProperty.Value;
|
|
83
|
-
private static void SetCurrentPlugin(IUcoPlugin? plugin) => _pluginProperty.Value = plugin;
|
|
84
|
-
|
|
85
|
-
public static LogLevel LogLevel
|
|
86
|
-
{
|
|
87
|
-
get => Instance.unityConnectionConfig.LogLevel;
|
|
88
|
-
set
|
|
89
|
-
{
|
|
90
|
-
Instance.unityConnectionConfig.LogLevel = value;
|
|
91
|
-
ApplyLogLevel(value);
|
|
92
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
public static string Host
|
|
96
|
-
{
|
|
97
|
-
get => Instance.unityConnectionConfig.Host;
|
|
98
|
-
set
|
|
99
|
-
{
|
|
100
|
-
Instance.unityConnectionConfig.Host = value;
|
|
101
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
public static string? LocalToken
|
|
105
|
-
{
|
|
106
|
-
get => Instance.unityConnectionConfig.LocalToken;
|
|
107
|
-
set
|
|
108
|
-
{
|
|
109
|
-
Instance.unityConnectionConfig.LocalToken = value;
|
|
110
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
public static string LocalHost
|
|
114
|
-
{
|
|
115
|
-
get => Instance.unityConnectionConfig.LocalHost;
|
|
116
|
-
set
|
|
117
|
-
{
|
|
118
|
-
Instance.unityConnectionConfig.LocalHost = value;
|
|
119
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
public static bool KeepConnected
|
|
123
|
-
{
|
|
124
|
-
get => Instance.unityConnectionConfig.KeepConnected;
|
|
125
|
-
set
|
|
126
|
-
{
|
|
127
|
-
Instance.unityConnectionConfig.KeepConnected = value;
|
|
128
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
public static bool KeepServerRunning
|
|
132
|
-
{
|
|
133
|
-
get => Instance.unityConnectionConfig.KeepServerRunning;
|
|
134
|
-
set
|
|
135
|
-
{
|
|
136
|
-
Instance.unityConnectionConfig.KeepServerRunning = value;
|
|
137
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
// Legacy config field, kept so persisted JSON configs keep loading symmetrically.
|
|
141
|
-
// The Node.js server exposes a single HTTP transport; nothing branches on this
|
|
142
|
-
// value anymore — the default (streamableHttp) is the only effective mode.
|
|
143
|
-
public static TransportMethod TransportMethod
|
|
144
|
-
{
|
|
145
|
-
get => Instance.unityConnectionConfig.TransportMethod;
|
|
146
|
-
set
|
|
147
|
-
{
|
|
148
|
-
Instance.unityConnectionConfig.TransportMethod = value;
|
|
149
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
public static int TimeoutMs
|
|
153
|
-
{
|
|
154
|
-
get => Instance.unityConnectionConfig.TimeoutMs;
|
|
155
|
-
set
|
|
156
|
-
{
|
|
157
|
-
Instance.unityConnectionConfig.TimeoutMs = value;
|
|
158
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
public static int Port
|
|
162
|
-
{
|
|
163
|
-
get
|
|
164
|
-
{
|
|
165
|
-
if (Uri.TryCreate(Host, UriKind.Absolute, out var uri) && uri.Port > 0 && uri.Port <= Consts.Hub.MaxPort)
|
|
166
|
-
return uri.Port;
|
|
167
|
-
|
|
168
|
-
return GeneratePortFromDirectory();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public static string? Token
|
|
173
|
-
{
|
|
174
|
-
get => Instance.unityConnectionConfig.Token;
|
|
175
|
-
set
|
|
176
|
-
{
|
|
177
|
-
Instance.unityConnectionConfig.Token = value;
|
|
178
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
public static AuthOption AuthOption
|
|
182
|
-
{
|
|
183
|
-
get => Instance.unityConnectionConfig.AuthOption;
|
|
184
|
-
set
|
|
185
|
-
{
|
|
186
|
-
Instance.unityConnectionConfig.AuthOption = value;
|
|
187
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
public static ConnectionMode ConnectionMode
|
|
191
|
-
{
|
|
192
|
-
get => Instance.unityConnectionConfig.ConnectionMode;
|
|
193
|
-
set
|
|
194
|
-
{
|
|
195
|
-
Instance.unityConnectionConfig.ConnectionMode = value;
|
|
196
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
public static string? NodeServerPath
|
|
200
|
-
{
|
|
201
|
-
get => Instance.unityConnectionConfig.NodeServerPath;
|
|
202
|
-
set
|
|
203
|
-
{
|
|
204
|
-
Instance.unityConnectionConfig.NodeServerPath = value;
|
|
205
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// ── Safe-defaults (fail-closed) network gates ─────────────────────────────────
|
|
210
|
-
// Static facades over UnityConnectionConfig.{AllowLanBind, AllowInsecureRemoteHttp,
|
|
211
|
-
// ForceTokenWhenLanBind}. They route through NotifyChanged so the UI and
|
|
212
|
-
// configurators re-render after a toggle flip. See UnityConnectionConfig for the
|
|
213
|
-
// semantics and the migration notes about backward compatibility.
|
|
214
|
-
public static bool AllowLanBind
|
|
215
|
-
{
|
|
216
|
-
get => Instance.unityConnectionConfig.AllowLanBind;
|
|
217
|
-
set
|
|
218
|
-
{
|
|
219
|
-
Instance.unityConnectionConfig.AllowLanBind = value;
|
|
220
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
public static bool AllowInsecureRemoteHttp
|
|
224
|
-
{
|
|
225
|
-
get => Instance.unityConnectionConfig.AllowInsecureRemoteHttp;
|
|
226
|
-
set
|
|
227
|
-
{
|
|
228
|
-
Instance.unityConnectionConfig.AllowInsecureRemoteHttp = value;
|
|
229
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
public static bool ForceTokenWhenLanBind
|
|
233
|
-
{
|
|
234
|
-
get => Instance.unityConnectionConfig.ForceTokenWhenLanBind;
|
|
235
|
-
set
|
|
236
|
-
{
|
|
237
|
-
Instance.unityConnectionConfig.ForceTokenWhenLanBind = value;
|
|
238
|
-
NotifyChanged(Instance.unityConnectionConfig);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// 'new' is intentional: static dispatch on the subtype, instance logic lives in the base.
|
|
243
|
-
public static new ReadOnlyReactiveProperty<WsState> ConnectionState
|
|
244
|
-
=> ((UnityCopilotPlugin)Instance).ConnectionState;
|
|
245
|
-
public static new ReadOnlyReactiveProperty<bool> IsConnected
|
|
246
|
-
=> ((UnityCopilotPlugin)Instance).IsConnected;
|
|
247
|
-
|
|
248
|
-
public static new Task NotifyToolRequestCompleted(RequestToolCompletedData request, CancellationToken cancellationToken = default)
|
|
249
|
-
=> ((UnityCopilotPlugin)Instance).NotifyToolRequestCompleted(request, cancellationToken);
|
|
250
|
-
|
|
251
|
-
public static IDisposable SubscribeOnChanged(Action<UnityConnectionConfig> action, bool invokeImmediately = true)
|
|
252
|
-
{
|
|
253
|
-
if (action == null)
|
|
254
|
-
throw new ArgumentNullException(nameof(action));
|
|
255
|
-
|
|
256
|
-
var subscription = _onConfigChanged.Subscribe(action);
|
|
257
|
-
if (invokeImmediately)
|
|
258
|
-
{
|
|
259
|
-
try { action(Instance.unityConnectionConfig); }
|
|
260
|
-
catch (Exception e) { _logger.LogError(e, "{method}: exception invoking action immediately", nameof(SubscribeOnChanged)); }
|
|
261
|
-
}
|
|
262
|
-
return subscription;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
public static new Task<bool> ConnectIfNeeded(CancellationToken cancellationToken = default)
|
|
266
|
-
=> ((UnityCopilotPlugin)Instance).ConnectIfNeeded(cancellationToken);
|
|
267
|
-
|
|
268
|
-
public static new Task<bool> Connect(CancellationToken cancellationToken = default)
|
|
269
|
-
=> ((UnityCopilotPlugin)Instance).Connect(cancellationToken);
|
|
270
|
-
|
|
271
|
-
public new void DisconnectImmediate()
|
|
272
|
-
{
|
|
273
|
-
Editor.Utils.EditorToolExecutionScheduler.Shared.InvalidateInstance();
|
|
274
|
-
Editor.Utils.EditorOperationOwnerRegistry.InvalidateGeneration();
|
|
275
|
-
Editor.Utils.UnityAuthoringSafetyReloadGuard.InvalidateConfirmationPlans();
|
|
276
|
-
base.DisconnectImmediate();
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
public static void StaticDispose()
|
|
280
|
-
{
|
|
281
|
-
_logger.LogTrace("{method} called.", nameof(StaticDispose));
|
|
282
|
-
|
|
283
|
-
lock (_instanceMutex)
|
|
284
|
-
{
|
|
285
|
-
instance?.Dispose();
|
|
286
|
-
instance = null!;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
static void NotifyChanged(UnityConnectionConfig data)
|
|
291
|
-
{
|
|
292
|
-
try { _onConfigChanged.OnNext(data); }
|
|
293
|
-
catch (Exception e) { _logger.LogError(e, "{method}: exception", nameof(NotifyChanged)); }
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
3
|
+
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
4
|
+
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
5
|
+
│ Copyright (c) 2025 Ivan Murzak │
|
|
6
|
+
│ Licensed under the Apache License, Version 2.0. │
|
|
7
|
+
│ See the LICENSE file in the project root for more information. │
|
|
8
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#nullable enable
|
|
12
|
+
using System;
|
|
13
|
+
using System.Diagnostics.CodeAnalysis;
|
|
14
|
+
using System.IO;
|
|
15
|
+
using System.Runtime.InteropServices;
|
|
16
|
+
using System.Threading;
|
|
17
|
+
using System.Threading.Tasks;
|
|
18
|
+
using com.AtelierAI.Uco.Framework;
|
|
19
|
+
using WsState = com.AtelierAI.Uco.Framework.ConnectionState;
|
|
20
|
+
using com.AtelierAI.Uco.Framework.Common;
|
|
21
|
+
using com.AtelierAI.Uco.Framework.Common.Model;
|
|
22
|
+
using com.AtelierAI.Unity.Copilot.Utils;
|
|
23
|
+
using Microsoft.Extensions.Logging;
|
|
24
|
+
using R3;
|
|
25
|
+
|
|
26
|
+
namespace com.AtelierAI.Unity.Copilot
|
|
27
|
+
{
|
|
28
|
+
using static com.AtelierAI.Uco.Framework.Common.Consts.Uco.Server;
|
|
29
|
+
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
|
30
|
+
using LogLevel = com.AtelierAI.Unity.Copilot.Runtime.Utils.LogLevel;
|
|
31
|
+
|
|
32
|
+
public partial class UnityCopilotPluginEditor
|
|
33
|
+
{
|
|
34
|
+
static readonly Subject<UnityConnectionConfig> _onConfigChanged = new Subject<UnityConnectionConfig>();
|
|
35
|
+
static readonly ILogger _logger = UnityLoggerFactory.LoggerFactory.CreateLogger<UnityCopilotPluginEditor>();
|
|
36
|
+
static readonly object _instanceMutex = new();
|
|
37
|
+
|
|
38
|
+
static UnityCopilotPluginEditor instance = null!;
|
|
39
|
+
|
|
40
|
+
public static bool HasInstance
|
|
41
|
+
{
|
|
42
|
+
get
|
|
43
|
+
{
|
|
44
|
+
lock (_instanceMutex)
|
|
45
|
+
{
|
|
46
|
+
return instance != null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
public static UnityCopilotPluginEditor Instance
|
|
51
|
+
{
|
|
52
|
+
get
|
|
53
|
+
{
|
|
54
|
+
InitSingletonIfNeeded();
|
|
55
|
+
lock (_instanceMutex)
|
|
56
|
+
{
|
|
57
|
+
return instance;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public static void InitSingletonIfNeeded()
|
|
63
|
+
{
|
|
64
|
+
lock (_instanceMutex)
|
|
65
|
+
{
|
|
66
|
+
if (instance == null)
|
|
67
|
+
{
|
|
68
|
+
instance = new UnityCopilotPluginEditor();
|
|
69
|
+
if (instance == null)
|
|
70
|
+
{
|
|
71
|
+
_logger.LogWarning("{method}: UnityCopilotPluginEditor instance is null",
|
|
72
|
+
nameof(InitSingletonIfNeeded));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Replaces UcoFramework.UcoFramework static singleton behavior
|
|
80
|
+
private static readonly ReactiveProperty<IUcoPlugin?> _pluginProperty = new(null);
|
|
81
|
+
public static ReadOnlyReactiveProperty<IUcoPlugin?> PluginProperty => _pluginProperty;
|
|
82
|
+
public static IUcoPlugin? CurrentPlugin => _pluginProperty.Value;
|
|
83
|
+
private static void SetCurrentPlugin(IUcoPlugin? plugin) => _pluginProperty.Value = plugin;
|
|
84
|
+
|
|
85
|
+
public static LogLevel LogLevel
|
|
86
|
+
{
|
|
87
|
+
get => Instance.unityConnectionConfig.LogLevel;
|
|
88
|
+
set
|
|
89
|
+
{
|
|
90
|
+
Instance.unityConnectionConfig.LogLevel = value;
|
|
91
|
+
ApplyLogLevel(value);
|
|
92
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
public static string Host
|
|
96
|
+
{
|
|
97
|
+
get => Instance.unityConnectionConfig.Host;
|
|
98
|
+
set
|
|
99
|
+
{
|
|
100
|
+
Instance.unityConnectionConfig.Host = value;
|
|
101
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
public static string? LocalToken
|
|
105
|
+
{
|
|
106
|
+
get => Instance.unityConnectionConfig.LocalToken;
|
|
107
|
+
set
|
|
108
|
+
{
|
|
109
|
+
Instance.unityConnectionConfig.LocalToken = value;
|
|
110
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
public static string LocalHost
|
|
114
|
+
{
|
|
115
|
+
get => Instance.unityConnectionConfig.LocalHost;
|
|
116
|
+
set
|
|
117
|
+
{
|
|
118
|
+
Instance.unityConnectionConfig.LocalHost = value;
|
|
119
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
public static bool KeepConnected
|
|
123
|
+
{
|
|
124
|
+
get => Instance.unityConnectionConfig.KeepConnected;
|
|
125
|
+
set
|
|
126
|
+
{
|
|
127
|
+
Instance.unityConnectionConfig.KeepConnected = value;
|
|
128
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
public static bool KeepServerRunning
|
|
132
|
+
{
|
|
133
|
+
get => Instance.unityConnectionConfig.KeepServerRunning;
|
|
134
|
+
set
|
|
135
|
+
{
|
|
136
|
+
Instance.unityConnectionConfig.KeepServerRunning = value;
|
|
137
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Legacy config field, kept so persisted JSON configs keep loading symmetrically.
|
|
141
|
+
// The Node.js server exposes a single HTTP transport; nothing branches on this
|
|
142
|
+
// value anymore — the default (streamableHttp) is the only effective mode.
|
|
143
|
+
public static TransportMethod TransportMethod
|
|
144
|
+
{
|
|
145
|
+
get => Instance.unityConnectionConfig.TransportMethod;
|
|
146
|
+
set
|
|
147
|
+
{
|
|
148
|
+
Instance.unityConnectionConfig.TransportMethod = value;
|
|
149
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
public static int TimeoutMs
|
|
153
|
+
{
|
|
154
|
+
get => Instance.unityConnectionConfig.TimeoutMs;
|
|
155
|
+
set
|
|
156
|
+
{
|
|
157
|
+
Instance.unityConnectionConfig.TimeoutMs = value;
|
|
158
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
public static int Port
|
|
162
|
+
{
|
|
163
|
+
get
|
|
164
|
+
{
|
|
165
|
+
if (Uri.TryCreate(Host, UriKind.Absolute, out var uri) && uri.Port > 0 && uri.Port <= Consts.Hub.MaxPort)
|
|
166
|
+
return uri.Port;
|
|
167
|
+
|
|
168
|
+
return GeneratePortFromDirectory();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public static string? Token
|
|
173
|
+
{
|
|
174
|
+
get => Instance.unityConnectionConfig.Token;
|
|
175
|
+
set
|
|
176
|
+
{
|
|
177
|
+
Instance.unityConnectionConfig.Token = value;
|
|
178
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
public static AuthOption AuthOption
|
|
182
|
+
{
|
|
183
|
+
get => Instance.unityConnectionConfig.AuthOption;
|
|
184
|
+
set
|
|
185
|
+
{
|
|
186
|
+
Instance.unityConnectionConfig.AuthOption = value;
|
|
187
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
public static ConnectionMode ConnectionMode
|
|
191
|
+
{
|
|
192
|
+
get => Instance.unityConnectionConfig.ConnectionMode;
|
|
193
|
+
set
|
|
194
|
+
{
|
|
195
|
+
Instance.unityConnectionConfig.ConnectionMode = value;
|
|
196
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
public static string? NodeServerPath
|
|
200
|
+
{
|
|
201
|
+
get => Instance.unityConnectionConfig.NodeServerPath;
|
|
202
|
+
set
|
|
203
|
+
{
|
|
204
|
+
Instance.unityConnectionConfig.NodeServerPath = value;
|
|
205
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ── Safe-defaults (fail-closed) network gates ─────────────────────────────────
|
|
210
|
+
// Static facades over UnityConnectionConfig.{AllowLanBind, AllowInsecureRemoteHttp,
|
|
211
|
+
// ForceTokenWhenLanBind}. They route through NotifyChanged so the UI and
|
|
212
|
+
// configurators re-render after a toggle flip. See UnityConnectionConfig for the
|
|
213
|
+
// semantics and the migration notes about backward compatibility.
|
|
214
|
+
public static bool AllowLanBind
|
|
215
|
+
{
|
|
216
|
+
get => Instance.unityConnectionConfig.AllowLanBind;
|
|
217
|
+
set
|
|
218
|
+
{
|
|
219
|
+
Instance.unityConnectionConfig.AllowLanBind = value;
|
|
220
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
public static bool AllowInsecureRemoteHttp
|
|
224
|
+
{
|
|
225
|
+
get => Instance.unityConnectionConfig.AllowInsecureRemoteHttp;
|
|
226
|
+
set
|
|
227
|
+
{
|
|
228
|
+
Instance.unityConnectionConfig.AllowInsecureRemoteHttp = value;
|
|
229
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
public static bool ForceTokenWhenLanBind
|
|
233
|
+
{
|
|
234
|
+
get => Instance.unityConnectionConfig.ForceTokenWhenLanBind;
|
|
235
|
+
set
|
|
236
|
+
{
|
|
237
|
+
Instance.unityConnectionConfig.ForceTokenWhenLanBind = value;
|
|
238
|
+
NotifyChanged(Instance.unityConnectionConfig);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// 'new' is intentional: static dispatch on the subtype, instance logic lives in the base.
|
|
243
|
+
public static new ReadOnlyReactiveProperty<WsState> ConnectionState
|
|
244
|
+
=> ((UnityCopilotPlugin)Instance).ConnectionState;
|
|
245
|
+
public static new ReadOnlyReactiveProperty<bool> IsConnected
|
|
246
|
+
=> ((UnityCopilotPlugin)Instance).IsConnected;
|
|
247
|
+
|
|
248
|
+
public static new Task NotifyToolRequestCompleted(RequestToolCompletedData request, CancellationToken cancellationToken = default)
|
|
249
|
+
=> ((UnityCopilotPlugin)Instance).NotifyToolRequestCompleted(request, cancellationToken);
|
|
250
|
+
|
|
251
|
+
public static IDisposable SubscribeOnChanged(Action<UnityConnectionConfig> action, bool invokeImmediately = true)
|
|
252
|
+
{
|
|
253
|
+
if (action == null)
|
|
254
|
+
throw new ArgumentNullException(nameof(action));
|
|
255
|
+
|
|
256
|
+
var subscription = _onConfigChanged.Subscribe(action);
|
|
257
|
+
if (invokeImmediately)
|
|
258
|
+
{
|
|
259
|
+
try { action(Instance.unityConnectionConfig); }
|
|
260
|
+
catch (Exception e) { _logger.LogError(e, "{method}: exception invoking action immediately", nameof(SubscribeOnChanged)); }
|
|
261
|
+
}
|
|
262
|
+
return subscription;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
public static new Task<bool> ConnectIfNeeded(CancellationToken cancellationToken = default)
|
|
266
|
+
=> ((UnityCopilotPlugin)Instance).ConnectIfNeeded(cancellationToken);
|
|
267
|
+
|
|
268
|
+
public static new Task<bool> Connect(CancellationToken cancellationToken = default)
|
|
269
|
+
=> ((UnityCopilotPlugin)Instance).Connect(cancellationToken);
|
|
270
|
+
|
|
271
|
+
public new void DisconnectImmediate()
|
|
272
|
+
{
|
|
273
|
+
Editor.Utils.EditorToolExecutionScheduler.Shared.InvalidateInstance();
|
|
274
|
+
Editor.Utils.EditorOperationOwnerRegistry.InvalidateGeneration();
|
|
275
|
+
Editor.Utils.UnityAuthoringSafetyReloadGuard.InvalidateConfirmationPlans();
|
|
276
|
+
base.DisconnectImmediate();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
public static void StaticDispose()
|
|
280
|
+
{
|
|
281
|
+
_logger.LogTrace("{method} called.", nameof(StaticDispose));
|
|
282
|
+
|
|
283
|
+
lock (_instanceMutex)
|
|
284
|
+
{
|
|
285
|
+
instance?.Dispose();
|
|
286
|
+
instance = null!;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
static void NotifyChanged(UnityConnectionConfig data)
|
|
291
|
+
{
|
|
292
|
+
try { _onConfigChanged.OnNext(data); }
|
|
293
|
+
catch (Exception e) { _logger.LogError(e, "{method}: exception", nameof(NotifyChanged)); }
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|