@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
|
@@ -1,230 +1,230 @@
|
|
|
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.Collections.Generic;
|
|
13
|
-
using System.Linq;
|
|
14
|
-
using com.AtelierAI.Uco.Framework.Common.Model;
|
|
15
|
-
using Microsoft.CodeAnalysis;
|
|
16
|
-
using Microsoft.CodeAnalysis.CSharp;
|
|
17
|
-
using UnityEditor;
|
|
18
|
-
using UnityEditor.Compilation;
|
|
19
|
-
|
|
20
|
-
namespace com.AtelierAI.Unity.Copilot.Editor.Utils
|
|
21
|
-
{
|
|
22
|
-
[InitializeOnLoad]
|
|
23
|
-
public static partial class ScriptUtils
|
|
24
|
-
{
|
|
25
|
-
private const string PendingNotificationKeysKey = "
|
|
26
|
-
private const string NotificationDataSeparator = "<
|
|
27
|
-
|
|
28
|
-
private static bool _processPendingScheduled = false;
|
|
29
|
-
|
|
30
|
-
// Store compilation messages (thread-safe with lock)
|
|
31
|
-
private static readonly List<CompilerMessage> _lastCompilationMessages = new List<CompilerMessage>();
|
|
32
|
-
private static readonly object _compilationMessagesLock = new object();
|
|
33
|
-
|
|
34
|
-
static ScriptUtils()
|
|
35
|
-
{
|
|
36
|
-
// Process any pending notifications after domain reload (successful compilation)
|
|
37
|
-
ScheduleProcessPendingNotifications();
|
|
38
|
-
|
|
39
|
-
// Also listen for compilation event to handle both success and failure cases
|
|
40
|
-
CompilationPipeline.assemblyCompilationFinished += OnAssemblyCompilationFinished;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
private static void OnAssemblyCompilationFinished(string assemblyPath, CompilerMessage[] messages)
|
|
44
|
-
{
|
|
45
|
-
lock (_compilationMessagesLock)
|
|
46
|
-
{
|
|
47
|
-
_lastCompilationMessages.Clear();
|
|
48
|
-
_lastCompilationMessages.AddRange(messages);
|
|
49
|
-
}
|
|
50
|
-
ScheduleProcessPendingNotifications();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private static void ScheduleProcessPendingNotifications()
|
|
54
|
-
{
|
|
55
|
-
if (_processPendingScheduled)
|
|
56
|
-
return;
|
|
57
|
-
|
|
58
|
-
_processPendingScheduled = true;
|
|
59
|
-
EditorApplication.update += ProcessPendingNotificationsOnce;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private static void ProcessPendingNotificationsOnce()
|
|
63
|
-
{
|
|
64
|
-
EditorApplication.update -= ProcessPendingNotificationsOnce;
|
|
65
|
-
|
|
66
|
-
if (!_processPendingScheduled)
|
|
67
|
-
return;
|
|
68
|
-
|
|
69
|
-
_processPendingScheduled = false;
|
|
70
|
-
ProcessPendingNotifications();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/// <summary>
|
|
74
|
-
/// Checks if the provided C# code has valid syntax.
|
|
75
|
-
/// This method uses Roslyn to parse the code and check for syntax errors.
|
|
76
|
-
/// </summary>
|
|
77
|
-
/// <param name="code">
|
|
78
|
-
/// <param name="errors"></param>
|
|
79
|
-
/// <returns>True if the code has valid syntax; otherwise, false.</returns>
|
|
80
|
-
public static bool IsValidCSharpSyntax(string code, out IEnumerable<Diagnostic> errors)
|
|
81
|
-
{
|
|
82
|
-
var syntaxTree = CSharpSyntaxTree.ParseText(code);
|
|
83
|
-
var diagnostics = syntaxTree.GetDiagnostics();
|
|
84
|
-
|
|
85
|
-
errors = diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error);
|
|
86
|
-
return !errors.Any();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/// <summary>
|
|
90
|
-
/// Schedules a notification to be sent after Unity compilation completes.
|
|
91
|
-
/// Uses SessionState to persist across domain reloads.
|
|
92
|
-
/// </summary>
|
|
93
|
-
/// <param name="requestId">The request ID to track</param>
|
|
94
|
-
/// <param name="filePath">The file path that was modified</param>
|
|
95
|
-
/// <param name="operationType">The type of operation performed</param>
|
|
96
|
-
public static void SchedulePostCompilationNotification(string requestId, string filePath, string operationType)
|
|
97
|
-
{
|
|
98
|
-
var notificationKey = $"
|
|
99
|
-
var notificationData = $"{requestId}{NotificationDataSeparator}{filePath}{NotificationDataSeparator}{operationType}";
|
|
100
|
-
|
|
101
|
-
// Store the notification data
|
|
102
|
-
SessionState.SetString(notificationKey, notificationData);
|
|
103
|
-
|
|
104
|
-
// Add to the key list
|
|
105
|
-
var existingKeys = SessionState.GetString(PendingNotificationKeysKey, string.Empty);
|
|
106
|
-
var keyList = string.IsNullOrEmpty(existingKeys)
|
|
107
|
-
? new List<string>()
|
|
108
|
-
: existingKeys.Split(',').Where(k => !string.IsNullOrEmpty(k)).ToList();
|
|
109
|
-
|
|
110
|
-
if (!keyList.Contains(notificationKey))
|
|
111
|
-
{
|
|
112
|
-
keyList.Add(notificationKey);
|
|
113
|
-
SessionState.SetString(PendingNotificationKeysKey, string.Join(",", keyList));
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/// <summary>
|
|
118
|
-
/// Called by InitializeOnLoad to process any pending notifications after compilation.
|
|
119
|
-
/// </summary>
|
|
120
|
-
public static void ProcessPendingNotifications()
|
|
121
|
-
{
|
|
122
|
-
// Get the list of pending notification keys from SessionState
|
|
123
|
-
var pendingKeys = SessionState.GetString(PendingNotificationKeysKey, string.Empty);
|
|
124
|
-
if (string.IsNullOrEmpty(pendingKeys))
|
|
125
|
-
return;
|
|
126
|
-
|
|
127
|
-
var keys = pendingKeys.Split(',').Where(k => !string.IsNullOrEmpty(k)).ToList();
|
|
128
|
-
if (keys.Count == 0)
|
|
129
|
-
return;
|
|
130
|
-
|
|
131
|
-
var processedKeys = new List<string>();
|
|
132
|
-
|
|
133
|
-
foreach (var key in keys)
|
|
134
|
-
{
|
|
135
|
-
var notificationData = SessionState.GetString(key, string.Empty);
|
|
136
|
-
if (string.IsNullOrEmpty(notificationData))
|
|
137
|
-
{
|
|
138
|
-
processedKeys.Add(key);
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
var parts = notificationData.Split(NotificationDataSeparator);
|
|
143
|
-
if (parts.Length != 3)
|
|
144
|
-
{
|
|
145
|
-
processedKeys.Add(key);
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
var requestId = parts[0];
|
|
150
|
-
var filePath = parts[1];
|
|
151
|
-
var operationType = parts[2];
|
|
152
|
-
|
|
153
|
-
// Check for compilation errors
|
|
154
|
-
var hasErrors = HasCompilationErrors();
|
|
155
|
-
|
|
156
|
-
ResponseCallTool response;
|
|
157
|
-
if (hasErrors)
|
|
158
|
-
{
|
|
159
|
-
var errorDetails = GetCompilationErrorDetails();
|
|
160
|
-
var message = $"[Warning] {operationType} completed: {filePath}, but compilation errors occurred. Details:\n{errorDetails}";
|
|
161
|
-
response = ResponseCallTool.Success(message).SetRequestID(requestId);
|
|
162
|
-
}
|
|
163
|
-
else
|
|
164
|
-
{
|
|
165
|
-
var message = $"[Success] {operationType} completed: {filePath}";
|
|
166
|
-
response = ResponseCallTool.Success(message).SetRequestID(requestId);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Send notification and mark for cleanup
|
|
170
|
-
_ = UnityCopilotPluginEditor.NotifyToolRequestCompleted(new RequestToolCompletedData
|
|
171
|
-
{
|
|
172
|
-
RequestId = requestId,
|
|
173
|
-
Result = response
|
|
174
|
-
});
|
|
175
|
-
processedKeys.Add(key);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// Clean up processed keys
|
|
179
|
-
foreach (var key in processedKeys)
|
|
180
|
-
SessionState.EraseString(key);
|
|
181
|
-
|
|
182
|
-
// Update the key list
|
|
183
|
-
var remainingKeys = keys.Except(processedKeys).ToList();
|
|
184
|
-
if (remainingKeys.Count > 0)
|
|
185
|
-
{
|
|
186
|
-
SessionState.SetString(PendingNotificationKeysKey, string.Join(",", remainingKeys));
|
|
187
|
-
}
|
|
188
|
-
else
|
|
189
|
-
{
|
|
190
|
-
SessionState.EraseString(PendingNotificationKeysKey);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/// <summary>
|
|
195
|
-
/// Checks if there are any compilation errors by examining Unity's console and compilation pipeline.
|
|
196
|
-
/// </summary>
|
|
197
|
-
/// <returns>True if compilation errors exist</returns>
|
|
198
|
-
public static bool HasCompilationErrors() => EditorUtility.scriptCompilationFailed;
|
|
199
|
-
|
|
200
|
-
/// <summary>
|
|
201
|
-
/// Retrieves detailed compilation error messages from the last compilation.
|
|
202
|
-
/// </summary>
|
|
203
|
-
/// <returns>Detailed compilation error messages</returns>
|
|
204
|
-
public static string GetCompilationErrorDetails()
|
|
205
|
-
{
|
|
206
|
-
var errors = new List<string>();
|
|
207
|
-
|
|
208
|
-
lock (_compilationMessagesLock)
|
|
209
|
-
{
|
|
210
|
-
foreach (var message in _lastCompilationMessages)
|
|
211
|
-
{
|
|
212
|
-
if (message.type == CompilerMessageType.Error)
|
|
213
|
-
errors.Add($"[{message.file}] {message.message} (Line: {message.line})");
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
if (errors.Count == 0)
|
|
218
|
-
{
|
|
219
|
-
// Since we can reliably check if compilation failed with EditorUtility.scriptCompilationFailed,
|
|
220
|
-
// but getting detailed messages is complex, provide a simple fallback
|
|
221
|
-
if (EditorUtility.scriptCompilationFailed)
|
|
222
|
-
return "Compilation errors detected. Please check the Unity Console window for detailed error messages.";
|
|
223
|
-
|
|
224
|
-
errors.Add("No detailed compilation errors found.");
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return string.Join("\n", errors);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
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.Collections.Generic;
|
|
13
|
+
using System.Linq;
|
|
14
|
+
using com.AtelierAI.Uco.Framework.Common.Model;
|
|
15
|
+
using Microsoft.CodeAnalysis;
|
|
16
|
+
using Microsoft.CodeAnalysis.CSharp;
|
|
17
|
+
using UnityEditor;
|
|
18
|
+
using UnityEditor.Compilation;
|
|
19
|
+
|
|
20
|
+
namespace com.AtelierAI.Unity.Copilot.Editor.Utils
|
|
21
|
+
{
|
|
22
|
+
[InitializeOnLoad]
|
|
23
|
+
public static partial class ScriptUtils
|
|
24
|
+
{
|
|
25
|
+
private const string PendingNotificationKeysKey = "UCO_PendingNotificationKeys";
|
|
26
|
+
private const string NotificationDataSeparator = "<UCO_SEP>";
|
|
27
|
+
|
|
28
|
+
private static bool _processPendingScheduled = false;
|
|
29
|
+
|
|
30
|
+
// Store compilation messages (thread-safe with lock)
|
|
31
|
+
private static readonly List<CompilerMessage> _lastCompilationMessages = new List<CompilerMessage>();
|
|
32
|
+
private static readonly object _compilationMessagesLock = new object();
|
|
33
|
+
|
|
34
|
+
static ScriptUtils()
|
|
35
|
+
{
|
|
36
|
+
// Process any pending notifications after domain reload (successful compilation)
|
|
37
|
+
ScheduleProcessPendingNotifications();
|
|
38
|
+
|
|
39
|
+
// Also listen for compilation event to handle both success and failure cases
|
|
40
|
+
CompilationPipeline.assemblyCompilationFinished += OnAssemblyCompilationFinished;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private static void OnAssemblyCompilationFinished(string assemblyPath, CompilerMessage[] messages)
|
|
44
|
+
{
|
|
45
|
+
lock (_compilationMessagesLock)
|
|
46
|
+
{
|
|
47
|
+
_lastCompilationMessages.Clear();
|
|
48
|
+
_lastCompilationMessages.AddRange(messages);
|
|
49
|
+
}
|
|
50
|
+
ScheduleProcessPendingNotifications();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private static void ScheduleProcessPendingNotifications()
|
|
54
|
+
{
|
|
55
|
+
if (_processPendingScheduled)
|
|
56
|
+
return;
|
|
57
|
+
|
|
58
|
+
_processPendingScheduled = true;
|
|
59
|
+
EditorApplication.update += ProcessPendingNotificationsOnce;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private static void ProcessPendingNotificationsOnce()
|
|
63
|
+
{
|
|
64
|
+
EditorApplication.update -= ProcessPendingNotificationsOnce;
|
|
65
|
+
|
|
66
|
+
if (!_processPendingScheduled)
|
|
67
|
+
return;
|
|
68
|
+
|
|
69
|
+
_processPendingScheduled = false;
|
|
70
|
+
ProcessPendingNotifications();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// <summary>
|
|
74
|
+
/// Checks if the provided C# code has valid syntax.
|
|
75
|
+
/// This method uses Roslyn to parse the code and check for syntax errors.
|
|
76
|
+
/// </summary>
|
|
77
|
+
/// <param name="code">
|
|
78
|
+
/// <param name="errors"></param>
|
|
79
|
+
/// <returns>True if the code has valid syntax; otherwise, false.</returns>
|
|
80
|
+
public static bool IsValidCSharpSyntax(string code, out IEnumerable<Diagnostic> errors)
|
|
81
|
+
{
|
|
82
|
+
var syntaxTree = CSharpSyntaxTree.ParseText(code);
|
|
83
|
+
var diagnostics = syntaxTree.GetDiagnostics();
|
|
84
|
+
|
|
85
|
+
errors = diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error);
|
|
86
|
+
return !errors.Any();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// <summary>
|
|
90
|
+
/// Schedules a notification to be sent after Unity compilation completes.
|
|
91
|
+
/// Uses SessionState to persist across domain reloads.
|
|
92
|
+
/// </summary>
|
|
93
|
+
/// <param name="requestId">The request ID to track</param>
|
|
94
|
+
/// <param name="filePath">The file path that was modified</param>
|
|
95
|
+
/// <param name="operationType">The type of operation performed</param>
|
|
96
|
+
public static void SchedulePostCompilationNotification(string requestId, string filePath, string operationType)
|
|
97
|
+
{
|
|
98
|
+
var notificationKey = $"UCO_PendingNotification_{requestId}";
|
|
99
|
+
var notificationData = $"{requestId}{NotificationDataSeparator}{filePath}{NotificationDataSeparator}{operationType}";
|
|
100
|
+
|
|
101
|
+
// Store the notification data
|
|
102
|
+
SessionState.SetString(notificationKey, notificationData);
|
|
103
|
+
|
|
104
|
+
// Add to the key list
|
|
105
|
+
var existingKeys = SessionState.GetString(PendingNotificationKeysKey, string.Empty);
|
|
106
|
+
var keyList = string.IsNullOrEmpty(existingKeys)
|
|
107
|
+
? new List<string>()
|
|
108
|
+
: existingKeys.Split(',').Where(k => !string.IsNullOrEmpty(k)).ToList();
|
|
109
|
+
|
|
110
|
+
if (!keyList.Contains(notificationKey))
|
|
111
|
+
{
|
|
112
|
+
keyList.Add(notificationKey);
|
|
113
|
+
SessionState.SetString(PendingNotificationKeysKey, string.Join(",", keyList));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// <summary>
|
|
118
|
+
/// Called by InitializeOnLoad to process any pending notifications after compilation.
|
|
119
|
+
/// </summary>
|
|
120
|
+
public static void ProcessPendingNotifications()
|
|
121
|
+
{
|
|
122
|
+
// Get the list of pending notification keys from SessionState
|
|
123
|
+
var pendingKeys = SessionState.GetString(PendingNotificationKeysKey, string.Empty);
|
|
124
|
+
if (string.IsNullOrEmpty(pendingKeys))
|
|
125
|
+
return;
|
|
126
|
+
|
|
127
|
+
var keys = pendingKeys.Split(',').Where(k => !string.IsNullOrEmpty(k)).ToList();
|
|
128
|
+
if (keys.Count == 0)
|
|
129
|
+
return;
|
|
130
|
+
|
|
131
|
+
var processedKeys = new List<string>();
|
|
132
|
+
|
|
133
|
+
foreach (var key in keys)
|
|
134
|
+
{
|
|
135
|
+
var notificationData = SessionState.GetString(key, string.Empty);
|
|
136
|
+
if (string.IsNullOrEmpty(notificationData))
|
|
137
|
+
{
|
|
138
|
+
processedKeys.Add(key);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var parts = notificationData.Split(NotificationDataSeparator);
|
|
143
|
+
if (parts.Length != 3)
|
|
144
|
+
{
|
|
145
|
+
processedKeys.Add(key);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
var requestId = parts[0];
|
|
150
|
+
var filePath = parts[1];
|
|
151
|
+
var operationType = parts[2];
|
|
152
|
+
|
|
153
|
+
// Check for compilation errors
|
|
154
|
+
var hasErrors = HasCompilationErrors();
|
|
155
|
+
|
|
156
|
+
ResponseCallTool response;
|
|
157
|
+
if (hasErrors)
|
|
158
|
+
{
|
|
159
|
+
var errorDetails = GetCompilationErrorDetails();
|
|
160
|
+
var message = $"[Warning] {operationType} completed: {filePath}, but compilation errors occurred. Details:\n{errorDetails}";
|
|
161
|
+
response = ResponseCallTool.Success(message).SetRequestID(requestId);
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
{
|
|
165
|
+
var message = $"[Success] {operationType} completed: {filePath}";
|
|
166
|
+
response = ResponseCallTool.Success(message).SetRequestID(requestId);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Send notification and mark for cleanup
|
|
170
|
+
_ = UnityCopilotPluginEditor.NotifyToolRequestCompleted(new RequestToolCompletedData
|
|
171
|
+
{
|
|
172
|
+
RequestId = requestId,
|
|
173
|
+
Result = response
|
|
174
|
+
});
|
|
175
|
+
processedKeys.Add(key);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Clean up processed keys
|
|
179
|
+
foreach (var key in processedKeys)
|
|
180
|
+
SessionState.EraseString(key);
|
|
181
|
+
|
|
182
|
+
// Update the key list
|
|
183
|
+
var remainingKeys = keys.Except(processedKeys).ToList();
|
|
184
|
+
if (remainingKeys.Count > 0)
|
|
185
|
+
{
|
|
186
|
+
SessionState.SetString(PendingNotificationKeysKey, string.Join(",", remainingKeys));
|
|
187
|
+
}
|
|
188
|
+
else
|
|
189
|
+
{
|
|
190
|
+
SessionState.EraseString(PendingNotificationKeysKey);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/// <summary>
|
|
195
|
+
/// Checks if there are any compilation errors by examining Unity's console and compilation pipeline.
|
|
196
|
+
/// </summary>
|
|
197
|
+
/// <returns>True if compilation errors exist</returns>
|
|
198
|
+
public static bool HasCompilationErrors() => EditorUtility.scriptCompilationFailed;
|
|
199
|
+
|
|
200
|
+
/// <summary>
|
|
201
|
+
/// Retrieves detailed compilation error messages from the last compilation.
|
|
202
|
+
/// </summary>
|
|
203
|
+
/// <returns>Detailed compilation error messages</returns>
|
|
204
|
+
public static string GetCompilationErrorDetails()
|
|
205
|
+
{
|
|
206
|
+
var errors = new List<string>();
|
|
207
|
+
|
|
208
|
+
lock (_compilationMessagesLock)
|
|
209
|
+
{
|
|
210
|
+
foreach (var message in _lastCompilationMessages)
|
|
211
|
+
{
|
|
212
|
+
if (message.type == CompilerMessageType.Error)
|
|
213
|
+
errors.Add($"[{message.file}] {message.message} (Line: {message.line})");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (errors.Count == 0)
|
|
218
|
+
{
|
|
219
|
+
// Since we can reliably check if compilation failed with EditorUtility.scriptCompilationFailed,
|
|
220
|
+
// but getting detailed messages is complex, provide a simple fallback
|
|
221
|
+
if (EditorUtility.scriptCompilationFailed)
|
|
222
|
+
return "Compilation errors detected. Please check the Unity Console window for detailed error messages.";
|
|
223
|
+
|
|
224
|
+
errors.Add("No detailed compilation errors found.");
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return string.Join("\n", errors);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
230
|
}
|