@atelierai/uco 1.0.6 → 1.0.8
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 +32 -0
- package/README.md +7 -8
- package/bin/server.mjs +1 -1
- package/bin/stub-plugin.mjs +3 -3
- package/dist/codegen/coerce.js +1 -1
- package/dist/codegen/coerce.js.map +1 -1
- package/dist/codegen/emit.js +2 -2
- package/dist/codegen/emit.js.map +1 -1
- package/dist/codegen/refs.js +1 -1
- package/dist/codegen/refs.js.map +1 -1
- package/dist/codegen/types.js +1 -1
- package/dist/codegen/types.js.map +1 -1
- package/dist/commands/call.js +1 -1
- package/dist/commands/call.js.map +1 -1
- package/dist/commands/devops/configure.js +1 -1
- package/dist/commands/devops/configure.js.map +1 -1
- package/dist/commands/devops/index.js +0 -4
- package/dist/commands/devops/index.js.map +1 -1
- package/dist/commands/devops/install-plugin.js +1 -1
- package/dist/commands/devops/install-plugin.js.map +1 -1
- package/dist/commands/devops/open.js +7 -7
- package/dist/commands/devops/open.js.map +1 -1
- package/dist/commands/devops/status.js +3 -3
- package/dist/commands/devops/status.js.map +1 -1
- package/dist/commands/exec.js +1 -1
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/install.js +2 -2
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/prompt.js +2 -2
- package/dist/commands/prompt.js.map +1 -1
- package/dist/commands/resource.js +2 -2
- package/dist/commands/resource.js.map +1 -1
- package/dist/commands/update.js +1 -26
- package/dist/commands/update.js.map +1 -1
- package/dist/config/port.js +2 -2
- package/dist/config/port.js.map +1 -1
- package/dist/config/resolve.d.ts +1 -2
- package/dist/config/resolve.js +0 -12
- package/dist/config/resolve.js.map +1 -1
- package/dist/devops/lib/configure.d.ts +1 -1
- package/dist/devops/lib/configure.js +2 -2
- package/dist/devops/lib/configure.js.map +1 -1
- package/dist/devops/lib/install-plugin.d.ts +1 -1
- package/dist/devops/lib/install-plugin.js +1 -1
- package/dist/devops/lib/install-plugin.js.map +1 -1
- package/dist/devops/lib/install.d.ts +2 -2
- package/dist/devops/lib/install.js +5 -5
- package/dist/devops/lib/install.js.map +1 -1
- package/dist/devops/lib/open.js +11 -32
- package/dist/devops/lib/open.js.map +1 -1
- package/dist/devops/lib/remove-plugin.d.ts +1 -1
- package/dist/devops/lib/remove-plugin.js +3 -3
- package/dist/devops/lib/remove-plugin.js.map +1 -1
- package/dist/devops/lib/run-tool.d.ts +2 -2
- package/dist/devops/lib/run-tool.js +2 -2
- package/dist/devops/lib/types.d.ts +17 -54
- package/dist/devops/lib/types.js +2 -2
- package/dist/devops/lib/types.js.map +1 -1
- package/dist/devops/lib/update.d.ts +0 -15
- package/dist/devops/lib/update.js +2 -91
- package/dist/devops/lib/update.js.map +1 -1
- package/dist/devops/utils/agents.d.ts +0 -28
- package/dist/devops/utils/agents.js +0 -462
- package/dist/devops/utils/agents.js.map +1 -1
- package/dist/devops/utils/config.d.ts +9 -18
- package/dist/devops/utils/config.js +7 -20
- package/dist/devops/utils/config.js.map +1 -1
- package/dist/devops/utils/editor-cache.js +1 -1
- package/dist/devops/utils/editor-cache.js.map +1 -1
- package/dist/devops/utils/launch-error-dismiss.d.ts +2 -2
- package/dist/devops/utils/launch-error-dismiss.js +5 -5
- package/dist/devops/utils/manifest.d.ts +2 -2
- package/dist/devops/utils/manifest.js +3 -3
- package/dist/devops/utils/manifest.js.map +1 -1
- package/dist/devops/utils/port.d.ts +1 -1
- package/dist/devops/utils/port.js +1 -1
- package/dist/devops/utils/probe.d.ts +1 -1
- package/dist/devops/utils/probe.js +1 -1
- package/dist/devops/utils/ui.js +2 -2
- package/dist/devops/utils/ui.js.map +1 -1
- package/dist/devops/utils/unity-editor.js +4 -4
- package/dist/devops/utils/unity-editor.js.map +1 -1
- package/dist/devops/utils/unity-hub.js +1 -1
- package/dist/devops/utils/unity-hub.js.map +1 -1
- package/dist/devops/utils/unity-shutdown.d.ts +1 -1
- package/dist/devops/utils/unity-shutdown.js +1 -1
- package/dist/devops/utils/update-check.js +3 -3
- package/dist/devops/utils/update-check.js.map +1 -1
- package/dist/devops/utils/vendor.d.ts +2 -2
- package/dist/devops/utils/vendor.js +4 -4
- package/dist/devops/utils/vendor.js.map +1 -1
- package/dist/generated/tools.js +1 -1
- package/dist/generated/tools.js.map +1 -1
- package/dist/program.js +3 -3
- package/dist/program.js.map +1 -1
- package/dist/server/app.d.ts +5 -5
- package/dist/server/app.js +3 -3
- package/dist/server/app.js.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/rest/auth.d.ts +1 -1
- package/dist/server/rest/auth.js +3 -3
- package/dist/server/rest/auth.js.map +1 -1
- package/dist/server/rest/context.d.ts +2 -2
- package/dist/server/rest/forward.d.ts +2 -2
- package/dist/server/session/store.d.ts +3 -3
- package/dist/server/session/store.js +4 -4
- package/dist/server/session/store.js.map +1 -1
- package/dist/server/stub-client/scenarios.js +8 -8
- package/dist/server/stub-client/scenarios.js.map +1 -1
- package/dist/server/types.d.ts +11 -11
- package/dist/server/types.js +9 -9
- package/dist/server/types.js.map +1 -1
- package/dist/server/ws/hub.d.ts +8 -8
- package/dist/server/ws/hub.js +13 -13
- package/dist/server/ws/hub.js.map +1 -1
- package/dist/server/ws/rpc.d.ts +3 -3
- package/dist/server/ws/rpc.js +4 -4
- package/dist/server/ws/rpc.js.map +1 -1
- package/dist/transport/index.d.ts +1 -1
- package/dist/transport/index.js +3 -3
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/rest.js +1 -1
- package/dist/transport/rest.js.map +1 -1
- package/docs/INSTALL.zh-CN.md +2 -3
- package/package.json +1 -1
- package/skills/uco-setup/SKILL.md +1 -1
- package/skills/unity-editor/references/diagnostics.md +24 -24
- 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/Branding/ProductInfo.cs +62 -62
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +1034 -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/Components/ExtensionPanel.cs +379 -379
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/MenuItems.cs +72 -72
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/UnityCopilotProjectSettingsProvider.cs +64 -64
- 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 +372 -372
- 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/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/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/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 +175 -175
- 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 +368 -368
- 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/NuGetLegacyMigrationTests.cs +304 -304
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +4 -4
- 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/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/dist/commands/devops/login.d.ts +0 -2
- package/dist/commands/devops/login.js +0 -29
- package/dist/commands/devops/login.js.map +0 -1
- package/dist/commands/devops/setup-mcp.d.ts +0 -2
- package/dist/commands/devops/setup-mcp.js +0 -41
- package/dist/commands/devops/setup-mcp.js.map +0 -1
- package/dist/devops/commands-upstream/bootstrap-local.d.ts +0 -17
- package/dist/devops/commands-upstream/bootstrap-local.js +0 -87
- package/dist/devops/commands-upstream/bootstrap-local.js.map +0 -1
- package/dist/devops/commands-upstream/close.d.ts +0 -57
- package/dist/devops/commands-upstream/close.js +0 -188
- package/dist/devops/commands-upstream/close.js.map +0 -1
- package/dist/devops/commands-upstream/configure.d.ts +0 -2
- package/dist/devops/commands-upstream/configure.js +0 -87
- package/dist/devops/commands-upstream/configure.js.map +0 -1
- package/dist/devops/commands-upstream/create-project.d.ts +0 -2
- package/dist/devops/commands-upstream/create-project.js +0 -43
- package/dist/devops/commands-upstream/create-project.js.map +0 -1
- package/dist/devops/commands-upstream/install-plugin.d.ts +0 -2
- package/dist/devops/commands-upstream/install-plugin.js +0 -64
- package/dist/devops/commands-upstream/install-plugin.js.map +0 -1
- package/dist/devops/commands-upstream/install-unity.d.ts +0 -2
- package/dist/devops/commands-upstream/install-unity.js +0 -72
- package/dist/devops/commands-upstream/install-unity.js.map +0 -1
- package/dist/devops/commands-upstream/login.d.ts +0 -2
- package/dist/devops/commands-upstream/login.js +0 -33
- package/dist/devops/commands-upstream/login.js.map +0 -1
- package/dist/devops/commands-upstream/open.d.ts +0 -32
- package/dist/devops/commands-upstream/open.js +0 -282
- package/dist/devops/commands-upstream/open.js.map +0 -1
- package/dist/devops/commands-upstream/remove-plugin.d.ts +0 -2
- package/dist/devops/commands-upstream/remove-plugin.js +0 -41
- package/dist/devops/commands-upstream/remove-plugin.js.map +0 -1
- package/dist/devops/commands-upstream/run-system-tool.d.ts +0 -1
- package/dist/devops/commands-upstream/run-system-tool.js +0 -13
- package/dist/devops/commands-upstream/run-system-tool.js.map +0 -1
- package/dist/devops/commands-upstream/run-tool-builder.d.ts +0 -25
- package/dist/devops/commands-upstream/run-tool-builder.js +0 -125
- package/dist/devops/commands-upstream/run-tool-builder.js.map +0 -1
- package/dist/devops/commands-upstream/run-tool.d.ts +0 -1
- package/dist/devops/commands-upstream/run-tool.js +0 -13
- package/dist/devops/commands-upstream/run-tool.js.map +0 -1
- package/dist/devops/commands-upstream/setup-mcp.d.ts +0 -2
- package/dist/devops/commands-upstream/setup-mcp.js +0 -68
- package/dist/devops/commands-upstream/setup-mcp.js.map +0 -1
- package/dist/devops/commands-upstream/setup-skills.d.ts +0 -2
- package/dist/devops/commands-upstream/setup-skills.js +0 -167
- package/dist/devops/commands-upstream/setup-skills.js.map +0 -1
- package/dist/devops/commands-upstream/status.d.ts +0 -2
- package/dist/devops/commands-upstream/status.js +0 -87
- package/dist/devops/commands-upstream/status.js.map +0 -1
- package/dist/devops/commands-upstream/update.d.ts +0 -2
- package/dist/devops/commands-upstream/update.js +0 -77
- package/dist/devops/commands-upstream/update.js.map +0 -1
- package/dist/devops/commands-upstream/wait-for-ready.d.ts +0 -2
- package/dist/devops/commands-upstream/wait-for-ready.js +0 -93
- package/dist/devops/commands-upstream/wait-for-ready.js.map +0 -1
- package/dist/devops/lib/setup-mcp.d.ts +0 -35
- package/dist/devops/lib/setup-mcp.js +0 -177
- package/dist/devops/lib/setup-mcp.js.map +0 -1
- package/dist/devops/utils/cloud-login.d.ts +0 -7
- package/dist/devops/utils/cloud-login.js +0 -56
- package/dist/devops/utils/cloud-login.js.map +0 -1
- /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/API/Tool/Script.Validate.cs
CHANGED
|
@@ -1,252 +1,252 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Design inspired by MCP for Unity (CoplayDev/unity-mcp), Copyright (c) Coplay Inc., MIT License.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
7
|
-
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
8
|
-
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
9
|
-
│ Copyright (c) 2025 Ivan Murzak │
|
|
10
|
-
│ Licensed under the Apache License, Version 2.0. │
|
|
11
|
-
│ See the LICENSE file in the project root for more information. │
|
|
12
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
#nullable enable
|
|
16
|
-
using System;
|
|
17
|
-
using System.Collections.Generic;
|
|
18
|
-
using System.ComponentModel;
|
|
19
|
-
using System.IO;
|
|
20
|
-
using System.Linq;
|
|
21
|
-
using com.AtelierAI.Uco.Framework;
|
|
22
|
-
using com.IvanMurzak.ReflectorNet.Utils;
|
|
23
|
-
using com.AtelierAI.Unity.Copilot.Utils;
|
|
24
|
-
using Microsoft.CodeAnalysis;
|
|
25
|
-
using Microsoft.CodeAnalysis.CSharp;
|
|
26
|
-
using RoslynDiagnostic = Microsoft.CodeAnalysis.Diagnostic;
|
|
27
|
-
|
|
28
|
-
namespace com.AtelierAI.Unity.Copilot.Editor.API
|
|
29
|
-
{
|
|
30
|
-
public static partial class Tool_Script
|
|
31
|
-
{
|
|
32
|
-
/// <summary>
|
|
33
|
-
/// Validation strictness for <see cref="Validate"/>.
|
|
34
|
-
/// </summary>
|
|
35
|
-
public enum ValidationLevel
|
|
36
|
-
{
|
|
37
|
-
/// <summary>Syntax-only: parser checks, no compilation. Fastest, no project references resolved.</summary>
|
|
38
|
-
Syntax = 0,
|
|
39
|
-
/// <summary>Syntax + semantic: type resolution against project assemblies (catches unknown types/methods/namespaces).</summary>
|
|
40
|
-
Semantic = 1,
|
|
41
|
-
/// <summary>Strict: Semantic + warnings-as-errors + nullable strictness. Catches latent issues but can be noisy.</summary>
|
|
42
|
-
Strict = 2,
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/// <summary>
|
|
46
|
-
/// Diagnostic entry returned by <see cref="Validate"/>.
|
|
47
|
-
/// </summary>
|
|
48
|
-
public class ValidationDiagnostic
|
|
49
|
-
{
|
|
50
|
-
public string Severity { get; set; } = string.Empty; // "Error" | "Warning" | "Info" | "Hidden"
|
|
51
|
-
public string Code { get; set; } = string.Empty; // e.g. "CS1002"
|
|
52
|
-
public string Message { get; set; } = string.Empty;
|
|
53
|
-
public int Line { get; set; } // 1-based
|
|
54
|
-
public int Column { get; set; } // 1-based
|
|
55
|
-
public int EndLine { get; set; } // 1-based
|
|
56
|
-
public int EndColumn { get; set; } // 1-based
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/// <summary>
|
|
60
|
-
/// Aggregated result returned by <see cref="Validate"/>.
|
|
61
|
-
/// </summary>
|
|
62
|
-
public class ValidationResult
|
|
63
|
-
{
|
|
64
|
-
public bool Ok { get; set; }
|
|
65
|
-
public ValidationLevel Level { get; set; }
|
|
66
|
-
public int ErrorCount { get; set; }
|
|
67
|
-
public int WarningCount { get; set; }
|
|
68
|
-
public ValidationDiagnostic[] Diagnostics { get; set; } = Array.Empty<ValidationDiagnostic>();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
public const string ScriptValidateToolId = "script-validate";
|
|
72
|
-
|
|
73
|
-
// Hard cap on input size to avoid OOM from runaway inputs. 1 MiB of C# source is already huge.
|
|
74
|
-
private const int MaxValidateCodeBytes = 1 * 1024 * 1024;
|
|
75
|
-
|
|
76
|
-
[UcoTool
|
|
77
|
-
(
|
|
78
|
-
ScriptValidateToolId,
|
|
79
|
-
Title = "Script / Validate",
|
|
80
|
-
ReadOnlyHint = true,
|
|
81
|
-
IdempotentHint = true
|
|
82
|
-
)]
|
|
83
|
-
[UcoSkillDescription("Validate C# source with Roslyn at three strictness levels (Syntax / Semantic / Strict). " +
|
|
84
|
-
"Does NOT execute or write to disk — safe pre-flight lint before '" + ScriptUpdateOrCreateToolId + "'. " +
|
|
85
|
-
"Strict / Semantic catch references to unknown namespaces, types, and methods against the project's loaded assemblies.")]
|
|
86
|
-
[UcoSkillBody("Validates a C# source string with Roslyn and returns structured diagnostics. " +
|
|
87
|
-
"Pure read-only — does NOT compile to an assembly, write any file, or invoke any code. " +
|
|
88
|
-
"Pair with '" + ScriptUpdateOrCreateToolId + "' as a pre-flight check before writing scripts to disk.\n\n" +
|
|
89
|
-
"## Inputs\n\n" +
|
|
90
|
-
"- `code` — required C# source text (the entire file contents). Throws if empty or larger than 1 MiB.\n" +
|
|
91
|
-
"- `level` — validation strictness:\n" +
|
|
92
|
-
" - `Syntax` (default) — parser-only, fastest. Catches malformed C# (`CS1002` missing `;`, `CS1513` unmatched braces, etc.).\n" +
|
|
93
|
-
" - `Semantic` — parser + symbol resolution against all loaded project assemblies. Catches `CS0246` (unknown type), `CS0103` (name not in scope), `CS1061` (no such member), unknown namespaces.\n" +
|
|
94
|
-
" - `Strict` — Semantic + warnings-as-errors + nullable context enabled. Useful but can be noisy on legacy code.\n" +
|
|
95
|
-
"- `fileName` — optional display name shown in `Diagnostic.Code` paths. Defaults to `Submitted.cs`.\n\n" +
|
|
96
|
-
"## Output\n\n" +
|
|
97
|
-
"Returns a `ValidationResult`:\n" +
|
|
98
|
-
"- `Ok` — true iff zero diagnostics with `Severity == Error`.\n" +
|
|
99
|
-
"- `Level` — the level that was actually run.\n" +
|
|
100
|
-
"- `ErrorCount` / `WarningCount` — totals.\n" +
|
|
101
|
-
"- `Diagnostics[]` — each with `Severity`, `Code` (e.g. `CS0246`), `Message`, and 1-based `Line`/`Column`/`EndLine`/`EndColumn`.\n\n" +
|
|
102
|
-
"## Notes\n\n" +
|
|
103
|
-
"- `Semantic` and `Strict` reuse the assembly reference set used by '" + ScriptExecuteToolId + "' " +
|
|
104
|
-
" (all non-dynamic assemblies in the current AppDomain with a non-empty `Location`).\n" +
|
|
105
|
-
"- Semantic resolution covers anything visible to your project — Unity APIs, packages, your own scripts " +
|
|
106
|
-
" that compiled successfully. If your project has compile errors, those types won't be resolvable here either.\n" +
|
|
107
|
-
"- This tool never runs the code. For execution use '" + ScriptExecuteToolId + "'.")]
|
|
108
|
-
[Description("Validates C# source via Roslyn at Syntax / Semantic / Strict levels without compiling to an assembly or " +
|
|
109
|
-
"writing any file. Use as a pre-flight check before '" + ScriptUpdateOrCreateToolId + "'. Semantic/Strict catch " +
|
|
110
|
-
"references to unknown namespaces, types, and methods against the project's loaded assemblies.")]
|
|
111
|
-
public static ValidationResult Validate
|
|
112
|
-
(
|
|
113
|
-
[Description("C# source code to validate (full file text).")]
|
|
114
|
-
string code,
|
|
115
|
-
[Description("Validation strictness. 'Syntax' (default) = parser only. 'Semantic' = parser + project-assembly symbol " +
|
|
116
|
-
"resolution (catches unknown types/methods/namespaces). 'Strict' = Semantic + warnings-as-errors + nullable.")]
|
|
117
|
-
ValidationLevel level = ValidationLevel.Syntax,
|
|
118
|
-
[Description("Optional file name shown in diagnostic locations. Defaults to 'Submitted.cs'.")]
|
|
119
|
-
string? fileName = null
|
|
120
|
-
)
|
|
121
|
-
{
|
|
122
|
-
if (string.IsNullOrEmpty(code))
|
|
123
|
-
throw new ArgumentException($"'{nameof(code)}' is null or empty. Please provide C# source to validate.", nameof(code));
|
|
124
|
-
|
|
125
|
-
// Defensive size cap. Roslyn handles large inputs but we don't want runaway memory from malformed clients.
|
|
126
|
-
// 2 bytes per char overestimates UTF-16 but is the right thing to compare against `byte` budget.
|
|
127
|
-
if ((long)code.Length * 2 > MaxValidateCodeBytes)
|
|
128
|
-
throw new ArgumentException(
|
|
129
|
-
$"'{nameof(code)}' is too large ({code.Length} chars). Limit: {MaxValidateCodeBytes / 1024} KiB.",
|
|
130
|
-
nameof(code));
|
|
131
|
-
|
|
132
|
-
var effectiveFileName = string.IsNullOrWhiteSpace(fileName) ? "Submitted.cs" : fileName!;
|
|
133
|
-
|
|
134
|
-
try
|
|
135
|
-
{
|
|
136
|
-
var syntaxTree = CSharpSyntaxTree.ParseText(code, path: effectiveFileName);
|
|
137
|
-
|
|
138
|
-
IEnumerable<RoslynDiagnostic> diagnostics;
|
|
139
|
-
|
|
140
|
-
if (level == ValidationLevel.Syntax)
|
|
141
|
-
{
|
|
142
|
-
diagnostics = syntaxTree.GetDiagnostics();
|
|
143
|
-
}
|
|
144
|
-
else
|
|
145
|
-
{
|
|
146
|
-
// Reused from Script.Execute.cs: aggregate non-dynamic AppDomain assemblies as MetadataReferences.
|
|
147
|
-
// Roslyn parsing/compilation is pure CPU and does NOT require Unity main thread.
|
|
148
|
-
var references = BuildProjectReferences();
|
|
149
|
-
|
|
150
|
-
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
|
151
|
-
.WithWarningLevel(4);
|
|
152
|
-
|
|
153
|
-
if (level == ValidationLevel.Strict)
|
|
154
|
-
{
|
|
155
|
-
options = options
|
|
156
|
-
.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
|
|
157
|
-
.WithNullableContextOptions(NullableContextOptions.Enable);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
var compilation = CSharpCompilation.Create(
|
|
161
|
-
assemblyName: "ValidationAssembly",
|
|
162
|
-
syntaxTrees: new[] { syntaxTree },
|
|
163
|
-
references: references,
|
|
164
|
-
options: options
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
// GetDiagnostics runs parse + declaration + method-body binding without emitting an assembly.
|
|
168
|
-
diagnostics = compilation.GetDiagnostics();
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
var diagList = diagnostics.ToList();
|
|
172
|
-
|
|
173
|
-
var errorCount = diagList.Count(d => d.Severity == DiagnosticSeverity.Error);
|
|
174
|
-
var warningCount = diagList.Count(d => d.Severity == DiagnosticSeverity.Warning);
|
|
175
|
-
|
|
176
|
-
return new ValidationResult
|
|
177
|
-
{
|
|
178
|
-
Ok = errorCount == 0,
|
|
179
|
-
Level = level,
|
|
180
|
-
ErrorCount = errorCount,
|
|
181
|
-
WarningCount = warningCount,
|
|
182
|
-
Diagnostics = diagList.Select(MapDiagnostic).ToArray(),
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
catch (ArgumentException)
|
|
186
|
-
{
|
|
187
|
-
// Preserve clean caller errors (size/empty checks above bubble through unchanged).
|
|
188
|
-
throw;
|
|
189
|
-
}
|
|
190
|
-
catch (Exception ex)
|
|
191
|
-
{
|
|
192
|
-
// Roslyn occasionally throws on pathological inputs; surface as a single synthetic error rather than 500ing.
|
|
193
|
-
return new ValidationResult
|
|
194
|
-
{
|
|
195
|
-
Ok = false,
|
|
196
|
-
Level = level,
|
|
197
|
-
ErrorCount = 1,
|
|
198
|
-
WarningCount = 0,
|
|
199
|
-
Diagnostics = new[]
|
|
200
|
-
{
|
|
201
|
-
new ValidationDiagnostic
|
|
202
|
-
{
|
|
203
|
-
Severity = "Error",
|
|
204
|
-
Code = "
|
|
205
|
-
Message = $"Validation failed internally: {ex.GetType().Name}: {ex.Message}",
|
|
206
|
-
Line = 1, Column = 1, EndLine = 1, EndColumn = 1,
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/// <summary>
|
|
214
|
-
/// Reused from Script.Execute.cs (ExecuteCSharpCode): build a MetadataReference[] from every loaded,
|
|
215
|
-
/// non-dynamic AppDomain assembly with a resolvable on-disk Location. Silently skips assemblies whose
|
|
216
|
-
/// files have moved or been unloaded — same forgiving behavior as the executor.
|
|
217
|
-
/// </summary>
|
|
218
|
-
static List<MetadataReference> BuildProjectReferences()
|
|
219
|
-
{
|
|
220
|
-
var result = new List<MetadataReference>();
|
|
221
|
-
foreach (var assembly in AssemblyUtils.AllAssemblies)
|
|
222
|
-
{
|
|
223
|
-
if (assembly.IsDynamic) continue;
|
|
224
|
-
if (string.IsNullOrEmpty(assembly.Location)) continue;
|
|
225
|
-
try
|
|
226
|
-
{
|
|
227
|
-
result.Add(MetadataReference.CreateFromFile(assembly.Location));
|
|
228
|
-
}
|
|
229
|
-
catch (DirectoryNotFoundException) { /* assembly unloaded / moved — skip */ }
|
|
230
|
-
catch (FileNotFoundException) { /* assembly unloaded / moved — skip */ }
|
|
231
|
-
catch (Exception) { /* defensive — never let a single bad assembly kill validation */ }
|
|
232
|
-
}
|
|
233
|
-
return result;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
static ValidationDiagnostic MapDiagnostic(RoslynDiagnostic d)
|
|
237
|
-
{
|
|
238
|
-
// Roslyn FileLinePositionSpan is 0-based; we surface 1-based to match human/IDE expectations.
|
|
239
|
-
var span = d.Location.GetLineSpan();
|
|
240
|
-
return new ValidationDiagnostic
|
|
241
|
-
{
|
|
242
|
-
Severity = d.Severity.ToString(),
|
|
243
|
-
Code = d.Id,
|
|
244
|
-
Message = d.GetMessage(),
|
|
245
|
-
Line = span.StartLinePosition.Line + 1,
|
|
246
|
-
Column = span.StartLinePosition.Character + 1,
|
|
247
|
-
EndLine = span.EndLinePosition.Line + 1,
|
|
248
|
-
EndColumn = span.EndLinePosition.Character + 1,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Design inspired by MCP for Unity (CoplayDev/unity-mcp), Copyright (c) Coplay Inc., MIT License.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
7
|
+
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
8
|
+
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
9
|
+
│ Copyright (c) 2025 Ivan Murzak │
|
|
10
|
+
│ Licensed under the Apache License, Version 2.0. │
|
|
11
|
+
│ See the LICENSE file in the project root for more information. │
|
|
12
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#nullable enable
|
|
16
|
+
using System;
|
|
17
|
+
using System.Collections.Generic;
|
|
18
|
+
using System.ComponentModel;
|
|
19
|
+
using System.IO;
|
|
20
|
+
using System.Linq;
|
|
21
|
+
using com.AtelierAI.Uco.Framework;
|
|
22
|
+
using com.IvanMurzak.ReflectorNet.Utils;
|
|
23
|
+
using com.AtelierAI.Unity.Copilot.Utils;
|
|
24
|
+
using Microsoft.CodeAnalysis;
|
|
25
|
+
using Microsoft.CodeAnalysis.CSharp;
|
|
26
|
+
using RoslynDiagnostic = Microsoft.CodeAnalysis.Diagnostic;
|
|
27
|
+
|
|
28
|
+
namespace com.AtelierAI.Unity.Copilot.Editor.API
|
|
29
|
+
{
|
|
30
|
+
public static partial class Tool_Script
|
|
31
|
+
{
|
|
32
|
+
/// <summary>
|
|
33
|
+
/// Validation strictness for <see cref="Validate"/>.
|
|
34
|
+
/// </summary>
|
|
35
|
+
public enum ValidationLevel
|
|
36
|
+
{
|
|
37
|
+
/// <summary>Syntax-only: parser checks, no compilation. Fastest, no project references resolved.</summary>
|
|
38
|
+
Syntax = 0,
|
|
39
|
+
/// <summary>Syntax + semantic: type resolution against project assemblies (catches unknown types/methods/namespaces).</summary>
|
|
40
|
+
Semantic = 1,
|
|
41
|
+
/// <summary>Strict: Semantic + warnings-as-errors + nullable strictness. Catches latent issues but can be noisy.</summary>
|
|
42
|
+
Strict = 2,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// <summary>
|
|
46
|
+
/// Diagnostic entry returned by <see cref="Validate"/>.
|
|
47
|
+
/// </summary>
|
|
48
|
+
public class ValidationDiagnostic
|
|
49
|
+
{
|
|
50
|
+
public string Severity { get; set; } = string.Empty; // "Error" | "Warning" | "Info" | "Hidden"
|
|
51
|
+
public string Code { get; set; } = string.Empty; // e.g. "CS1002"
|
|
52
|
+
public string Message { get; set; } = string.Empty;
|
|
53
|
+
public int Line { get; set; } // 1-based
|
|
54
|
+
public int Column { get; set; } // 1-based
|
|
55
|
+
public int EndLine { get; set; } // 1-based
|
|
56
|
+
public int EndColumn { get; set; } // 1-based
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// <summary>
|
|
60
|
+
/// Aggregated result returned by <see cref="Validate"/>.
|
|
61
|
+
/// </summary>
|
|
62
|
+
public class ValidationResult
|
|
63
|
+
{
|
|
64
|
+
public bool Ok { get; set; }
|
|
65
|
+
public ValidationLevel Level { get; set; }
|
|
66
|
+
public int ErrorCount { get; set; }
|
|
67
|
+
public int WarningCount { get; set; }
|
|
68
|
+
public ValidationDiagnostic[] Diagnostics { get; set; } = Array.Empty<ValidationDiagnostic>();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public const string ScriptValidateToolId = "script-validate";
|
|
72
|
+
|
|
73
|
+
// Hard cap on input size to avoid OOM from runaway inputs. 1 MiB of C# source is already huge.
|
|
74
|
+
private const int MaxValidateCodeBytes = 1 * 1024 * 1024;
|
|
75
|
+
|
|
76
|
+
[UcoTool
|
|
77
|
+
(
|
|
78
|
+
ScriptValidateToolId,
|
|
79
|
+
Title = "Script / Validate",
|
|
80
|
+
ReadOnlyHint = true,
|
|
81
|
+
IdempotentHint = true
|
|
82
|
+
)]
|
|
83
|
+
[UcoSkillDescription("Validate C# source with Roslyn at three strictness levels (Syntax / Semantic / Strict). " +
|
|
84
|
+
"Does NOT execute or write to disk — safe pre-flight lint before '" + ScriptUpdateOrCreateToolId + "'. " +
|
|
85
|
+
"Strict / Semantic catch references to unknown namespaces, types, and methods against the project's loaded assemblies.")]
|
|
86
|
+
[UcoSkillBody("Validates a C# source string with Roslyn and returns structured diagnostics. " +
|
|
87
|
+
"Pure read-only — does NOT compile to an assembly, write any file, or invoke any code. " +
|
|
88
|
+
"Pair with '" + ScriptUpdateOrCreateToolId + "' as a pre-flight check before writing scripts to disk.\n\n" +
|
|
89
|
+
"## Inputs\n\n" +
|
|
90
|
+
"- `code` — required C# source text (the entire file contents). Throws if empty or larger than 1 MiB.\n" +
|
|
91
|
+
"- `level` — validation strictness:\n" +
|
|
92
|
+
" - `Syntax` (default) — parser-only, fastest. Catches malformed C# (`CS1002` missing `;`, `CS1513` unmatched braces, etc.).\n" +
|
|
93
|
+
" - `Semantic` — parser + symbol resolution against all loaded project assemblies. Catches `CS0246` (unknown type), `CS0103` (name not in scope), `CS1061` (no such member), unknown namespaces.\n" +
|
|
94
|
+
" - `Strict` — Semantic + warnings-as-errors + nullable context enabled. Useful but can be noisy on legacy code.\n" +
|
|
95
|
+
"- `fileName` — optional display name shown in `Diagnostic.Code` paths. Defaults to `Submitted.cs`.\n\n" +
|
|
96
|
+
"## Output\n\n" +
|
|
97
|
+
"Returns a `ValidationResult`:\n" +
|
|
98
|
+
"- `Ok` — true iff zero diagnostics with `Severity == Error`.\n" +
|
|
99
|
+
"- `Level` — the level that was actually run.\n" +
|
|
100
|
+
"- `ErrorCount` / `WarningCount` — totals.\n" +
|
|
101
|
+
"- `Diagnostics[]` — each with `Severity`, `Code` (e.g. `CS0246`), `Message`, and 1-based `Line`/`Column`/`EndLine`/`EndColumn`.\n\n" +
|
|
102
|
+
"## Notes\n\n" +
|
|
103
|
+
"- `Semantic` and `Strict` reuse the assembly reference set used by '" + ScriptExecuteToolId + "' " +
|
|
104
|
+
" (all non-dynamic assemblies in the current AppDomain with a non-empty `Location`).\n" +
|
|
105
|
+
"- Semantic resolution covers anything visible to your project — Unity APIs, packages, your own scripts " +
|
|
106
|
+
" that compiled successfully. If your project has compile errors, those types won't be resolvable here either.\n" +
|
|
107
|
+
"- This tool never runs the code. For execution use '" + ScriptExecuteToolId + "'.")]
|
|
108
|
+
[Description("Validates C# source via Roslyn at Syntax / Semantic / Strict levels without compiling to an assembly or " +
|
|
109
|
+
"writing any file. Use as a pre-flight check before '" + ScriptUpdateOrCreateToolId + "'. Semantic/Strict catch " +
|
|
110
|
+
"references to unknown namespaces, types, and methods against the project's loaded assemblies.")]
|
|
111
|
+
public static ValidationResult Validate
|
|
112
|
+
(
|
|
113
|
+
[Description("C# source code to validate (full file text).")]
|
|
114
|
+
string code,
|
|
115
|
+
[Description("Validation strictness. 'Syntax' (default) = parser only. 'Semantic' = parser + project-assembly symbol " +
|
|
116
|
+
"resolution (catches unknown types/methods/namespaces). 'Strict' = Semantic + warnings-as-errors + nullable.")]
|
|
117
|
+
ValidationLevel level = ValidationLevel.Syntax,
|
|
118
|
+
[Description("Optional file name shown in diagnostic locations. Defaults to 'Submitted.cs'.")]
|
|
119
|
+
string? fileName = null
|
|
120
|
+
)
|
|
121
|
+
{
|
|
122
|
+
if (string.IsNullOrEmpty(code))
|
|
123
|
+
throw new ArgumentException($"'{nameof(code)}' is null or empty. Please provide C# source to validate.", nameof(code));
|
|
124
|
+
|
|
125
|
+
// Defensive size cap. Roslyn handles large inputs but we don't want runaway memory from malformed clients.
|
|
126
|
+
// 2 bytes per char overestimates UTF-16 but is the right thing to compare against `byte` budget.
|
|
127
|
+
if ((long)code.Length * 2 > MaxValidateCodeBytes)
|
|
128
|
+
throw new ArgumentException(
|
|
129
|
+
$"'{nameof(code)}' is too large ({code.Length} chars). Limit: {MaxValidateCodeBytes / 1024} KiB.",
|
|
130
|
+
nameof(code));
|
|
131
|
+
|
|
132
|
+
var effectiveFileName = string.IsNullOrWhiteSpace(fileName) ? "Submitted.cs" : fileName!;
|
|
133
|
+
|
|
134
|
+
try
|
|
135
|
+
{
|
|
136
|
+
var syntaxTree = CSharpSyntaxTree.ParseText(code, path: effectiveFileName);
|
|
137
|
+
|
|
138
|
+
IEnumerable<RoslynDiagnostic> diagnostics;
|
|
139
|
+
|
|
140
|
+
if (level == ValidationLevel.Syntax)
|
|
141
|
+
{
|
|
142
|
+
diagnostics = syntaxTree.GetDiagnostics();
|
|
143
|
+
}
|
|
144
|
+
else
|
|
145
|
+
{
|
|
146
|
+
// Reused from Script.Execute.cs: aggregate non-dynamic AppDomain assemblies as MetadataReferences.
|
|
147
|
+
// Roslyn parsing/compilation is pure CPU and does NOT require Unity main thread.
|
|
148
|
+
var references = BuildProjectReferences();
|
|
149
|
+
|
|
150
|
+
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
|
151
|
+
.WithWarningLevel(4);
|
|
152
|
+
|
|
153
|
+
if (level == ValidationLevel.Strict)
|
|
154
|
+
{
|
|
155
|
+
options = options
|
|
156
|
+
.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
|
|
157
|
+
.WithNullableContextOptions(NullableContextOptions.Enable);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
var compilation = CSharpCompilation.Create(
|
|
161
|
+
assemblyName: "ValidationAssembly",
|
|
162
|
+
syntaxTrees: new[] { syntaxTree },
|
|
163
|
+
references: references,
|
|
164
|
+
options: options
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// GetDiagnostics runs parse + declaration + method-body binding without emitting an assembly.
|
|
168
|
+
diagnostics = compilation.GetDiagnostics();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
var diagList = diagnostics.ToList();
|
|
172
|
+
|
|
173
|
+
var errorCount = diagList.Count(d => d.Severity == DiagnosticSeverity.Error);
|
|
174
|
+
var warningCount = diagList.Count(d => d.Severity == DiagnosticSeverity.Warning);
|
|
175
|
+
|
|
176
|
+
return new ValidationResult
|
|
177
|
+
{
|
|
178
|
+
Ok = errorCount == 0,
|
|
179
|
+
Level = level,
|
|
180
|
+
ErrorCount = errorCount,
|
|
181
|
+
WarningCount = warningCount,
|
|
182
|
+
Diagnostics = diagList.Select(MapDiagnostic).ToArray(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
catch (ArgumentException)
|
|
186
|
+
{
|
|
187
|
+
// Preserve clean caller errors (size/empty checks above bubble through unchanged).
|
|
188
|
+
throw;
|
|
189
|
+
}
|
|
190
|
+
catch (Exception ex)
|
|
191
|
+
{
|
|
192
|
+
// Roslyn occasionally throws on pathological inputs; surface as a single synthetic error rather than 500ing.
|
|
193
|
+
return new ValidationResult
|
|
194
|
+
{
|
|
195
|
+
Ok = false,
|
|
196
|
+
Level = level,
|
|
197
|
+
ErrorCount = 1,
|
|
198
|
+
WarningCount = 0,
|
|
199
|
+
Diagnostics = new[]
|
|
200
|
+
{
|
|
201
|
+
new ValidationDiagnostic
|
|
202
|
+
{
|
|
203
|
+
Severity = "Error",
|
|
204
|
+
Code = "UCO_VALIDATE_INTERNAL",
|
|
205
|
+
Message = $"Validation failed internally: {ex.GetType().Name}: {ex.Message}",
|
|
206
|
+
Line = 1, Column = 1, EndLine = 1, EndColumn = 1,
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/// <summary>
|
|
214
|
+
/// Reused from Script.Execute.cs (ExecuteCSharpCode): build a MetadataReference[] from every loaded,
|
|
215
|
+
/// non-dynamic AppDomain assembly with a resolvable on-disk Location. Silently skips assemblies whose
|
|
216
|
+
/// files have moved or been unloaded — same forgiving behavior as the executor.
|
|
217
|
+
/// </summary>
|
|
218
|
+
static List<MetadataReference> BuildProjectReferences()
|
|
219
|
+
{
|
|
220
|
+
var result = new List<MetadataReference>();
|
|
221
|
+
foreach (var assembly in AssemblyUtils.AllAssemblies)
|
|
222
|
+
{
|
|
223
|
+
if (assembly.IsDynamic) continue;
|
|
224
|
+
if (string.IsNullOrEmpty(assembly.Location)) continue;
|
|
225
|
+
try
|
|
226
|
+
{
|
|
227
|
+
result.Add(MetadataReference.CreateFromFile(assembly.Location));
|
|
228
|
+
}
|
|
229
|
+
catch (DirectoryNotFoundException) { /* assembly unloaded / moved — skip */ }
|
|
230
|
+
catch (FileNotFoundException) { /* assembly unloaded / moved — skip */ }
|
|
231
|
+
catch (Exception) { /* defensive — never let a single bad assembly kill validation */ }
|
|
232
|
+
}
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static ValidationDiagnostic MapDiagnostic(RoslynDiagnostic d)
|
|
237
|
+
{
|
|
238
|
+
// Roslyn FileLinePositionSpan is 0-based; we surface 1-based to match human/IDE expectations.
|
|
239
|
+
var span = d.Location.GetLineSpan();
|
|
240
|
+
return new ValidationDiagnostic
|
|
241
|
+
{
|
|
242
|
+
Severity = d.Severity.ToString(),
|
|
243
|
+
Code = d.Id,
|
|
244
|
+
Message = d.GetMessage(),
|
|
245
|
+
Line = span.StartLinePosition.Line + 1,
|
|
246
|
+
Column = span.StartLinePosition.Character + 1,
|
|
247
|
+
EndLine = span.EndLinePosition.Line + 1,
|
|
248
|
+
EndColumn = span.EndLinePosition.Character + 1,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|