@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.
Files changed (280) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +7 -8
  3. package/bin/server.mjs +1 -1
  4. package/bin/stub-plugin.mjs +3 -3
  5. package/dist/codegen/coerce.js +1 -1
  6. package/dist/codegen/coerce.js.map +1 -1
  7. package/dist/codegen/emit.js +2 -2
  8. package/dist/codegen/emit.js.map +1 -1
  9. package/dist/codegen/refs.js +1 -1
  10. package/dist/codegen/refs.js.map +1 -1
  11. package/dist/codegen/types.js +1 -1
  12. package/dist/codegen/types.js.map +1 -1
  13. package/dist/commands/call.js +1 -1
  14. package/dist/commands/call.js.map +1 -1
  15. package/dist/commands/devops/configure.js +1 -1
  16. package/dist/commands/devops/configure.js.map +1 -1
  17. package/dist/commands/devops/index.js +0 -4
  18. package/dist/commands/devops/index.js.map +1 -1
  19. package/dist/commands/devops/install-plugin.js +1 -1
  20. package/dist/commands/devops/install-plugin.js.map +1 -1
  21. package/dist/commands/devops/open.js +7 -7
  22. package/dist/commands/devops/open.js.map +1 -1
  23. package/dist/commands/devops/status.js +3 -3
  24. package/dist/commands/devops/status.js.map +1 -1
  25. package/dist/commands/exec.js +1 -1
  26. package/dist/commands/exec.js.map +1 -1
  27. package/dist/commands/install.js +2 -2
  28. package/dist/commands/install.js.map +1 -1
  29. package/dist/commands/prompt.js +2 -2
  30. package/dist/commands/prompt.js.map +1 -1
  31. package/dist/commands/resource.js +2 -2
  32. package/dist/commands/resource.js.map +1 -1
  33. package/dist/commands/update.js +1 -26
  34. package/dist/commands/update.js.map +1 -1
  35. package/dist/config/port.js +2 -2
  36. package/dist/config/port.js.map +1 -1
  37. package/dist/config/resolve.d.ts +1 -2
  38. package/dist/config/resolve.js +0 -12
  39. package/dist/config/resolve.js.map +1 -1
  40. package/dist/devops/lib/configure.d.ts +1 -1
  41. package/dist/devops/lib/configure.js +2 -2
  42. package/dist/devops/lib/configure.js.map +1 -1
  43. package/dist/devops/lib/install-plugin.d.ts +1 -1
  44. package/dist/devops/lib/install-plugin.js +1 -1
  45. package/dist/devops/lib/install-plugin.js.map +1 -1
  46. package/dist/devops/lib/install.d.ts +2 -2
  47. package/dist/devops/lib/install.js +5 -5
  48. package/dist/devops/lib/install.js.map +1 -1
  49. package/dist/devops/lib/open.js +11 -32
  50. package/dist/devops/lib/open.js.map +1 -1
  51. package/dist/devops/lib/remove-plugin.d.ts +1 -1
  52. package/dist/devops/lib/remove-plugin.js +3 -3
  53. package/dist/devops/lib/remove-plugin.js.map +1 -1
  54. package/dist/devops/lib/run-tool.d.ts +2 -2
  55. package/dist/devops/lib/run-tool.js +2 -2
  56. package/dist/devops/lib/types.d.ts +17 -54
  57. package/dist/devops/lib/types.js +2 -2
  58. package/dist/devops/lib/types.js.map +1 -1
  59. package/dist/devops/lib/update.d.ts +0 -15
  60. package/dist/devops/lib/update.js +2 -91
  61. package/dist/devops/lib/update.js.map +1 -1
  62. package/dist/devops/utils/agents.d.ts +0 -28
  63. package/dist/devops/utils/agents.js +0 -462
  64. package/dist/devops/utils/agents.js.map +1 -1
  65. package/dist/devops/utils/config.d.ts +9 -18
  66. package/dist/devops/utils/config.js +7 -20
  67. package/dist/devops/utils/config.js.map +1 -1
  68. package/dist/devops/utils/editor-cache.js +1 -1
  69. package/dist/devops/utils/editor-cache.js.map +1 -1
  70. package/dist/devops/utils/launch-error-dismiss.d.ts +2 -2
  71. package/dist/devops/utils/launch-error-dismiss.js +5 -5
  72. package/dist/devops/utils/manifest.d.ts +2 -2
  73. package/dist/devops/utils/manifest.js +3 -3
  74. package/dist/devops/utils/manifest.js.map +1 -1
  75. package/dist/devops/utils/port.d.ts +1 -1
  76. package/dist/devops/utils/port.js +1 -1
  77. package/dist/devops/utils/probe.d.ts +1 -1
  78. package/dist/devops/utils/probe.js +1 -1
  79. package/dist/devops/utils/ui.js +2 -2
  80. package/dist/devops/utils/ui.js.map +1 -1
  81. package/dist/devops/utils/unity-editor.js +4 -4
  82. package/dist/devops/utils/unity-editor.js.map +1 -1
  83. package/dist/devops/utils/unity-hub.js +1 -1
  84. package/dist/devops/utils/unity-hub.js.map +1 -1
  85. package/dist/devops/utils/unity-shutdown.d.ts +1 -1
  86. package/dist/devops/utils/unity-shutdown.js +1 -1
  87. package/dist/devops/utils/update-check.js +3 -3
  88. package/dist/devops/utils/update-check.js.map +1 -1
  89. package/dist/devops/utils/vendor.d.ts +2 -2
  90. package/dist/devops/utils/vendor.js +4 -4
  91. package/dist/devops/utils/vendor.js.map +1 -1
  92. package/dist/generated/tools.js +1 -1
  93. package/dist/generated/tools.js.map +1 -1
  94. package/dist/program.js +3 -3
  95. package/dist/program.js.map +1 -1
  96. package/dist/server/app.d.ts +5 -5
  97. package/dist/server/app.js +3 -3
  98. package/dist/server/app.js.map +1 -1
  99. package/dist/server/index.d.ts +2 -2
  100. package/dist/server/index.js +2 -2
  101. package/dist/server/index.js.map +1 -1
  102. package/dist/server/rest/auth.d.ts +1 -1
  103. package/dist/server/rest/auth.js +3 -3
  104. package/dist/server/rest/auth.js.map +1 -1
  105. package/dist/server/rest/context.d.ts +2 -2
  106. package/dist/server/rest/forward.d.ts +2 -2
  107. package/dist/server/session/store.d.ts +3 -3
  108. package/dist/server/session/store.js +4 -4
  109. package/dist/server/session/store.js.map +1 -1
  110. package/dist/server/stub-client/scenarios.js +8 -8
  111. package/dist/server/stub-client/scenarios.js.map +1 -1
  112. package/dist/server/types.d.ts +11 -11
  113. package/dist/server/types.js +9 -9
  114. package/dist/server/types.js.map +1 -1
  115. package/dist/server/ws/hub.d.ts +8 -8
  116. package/dist/server/ws/hub.js +13 -13
  117. package/dist/server/ws/hub.js.map +1 -1
  118. package/dist/server/ws/rpc.d.ts +3 -3
  119. package/dist/server/ws/rpc.js +4 -4
  120. package/dist/server/ws/rpc.js.map +1 -1
  121. package/dist/transport/index.d.ts +1 -1
  122. package/dist/transport/index.js +3 -3
  123. package/dist/transport/index.js.map +1 -1
  124. package/dist/transport/rest.js +1 -1
  125. package/dist/transport/rest.js.map +1 -1
  126. package/docs/INSTALL.zh-CN.md +2 -3
  127. package/package.json +1 -1
  128. package/skills/uco-setup/SKILL.md +1 -1
  129. package/skills/unity-editor/references/diagnostics.md +24 -24
  130. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetConfig.cs +132 -132
  131. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDependencyResolver.cs +237 -237
  132. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDownloader.cs +82 -82
  133. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/MenuItems.cs +247 -247
  134. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/ToolGroups.cs +153 -153
  135. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/SystemTool/Skills.Create.SkillBody.cs +155 -155
  136. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Console.GetLogs.cs +95 -95
  137. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Docs.HttpFetcher.cs +139 -139
  138. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Instance.ListAll.cs +72 -72
  139. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/PathReadHelper.cs +106 -106
  140. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Script.Validate.cs +252 -252
  141. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests/TestResultCollector.cs +537 -537
  142. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests.cs +400 -400
  143. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Branding/ProductInfo.cs +62 -62
  144. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +1034 -1034
  145. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Skills/Skill_InitialSetup.cs +197 -197
  146. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.Editor.cs +201 -201
  147. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.cs +67 -67
  148. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Components/ExtensionPanel.cs +379 -379
  149. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/MenuItems.cs +72 -72
  150. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/UnityCopilotProjectSettingsProvider.cs +64 -64
  151. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotListWindowBase.cs +393 -393
  152. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotWindowBase.cs +113 -113
  153. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.Connection.cs +3 -3
  154. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotFeatures.cs +195 -195
  155. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotServer.cs +372 -372
  156. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CreateGUI.cs +354 -354
  157. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.cs +78 -78
  158. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowInitializer.cs +47 -47
  159. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/SerializationCheckWindow.cs +190 -190
  160. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Build.cs +91 -91
  161. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Config.cs +298 -298
  162. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Static.cs +296 -296
  163. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.cs +69 -69
  164. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PackageUtils.cs +168 -168
  165. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PrefsKeyMigration.cs +119 -119
  166. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/SafeDefaultsGuard.cs +180 -180
  167. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ScriptUtils.cs +229 -229
  168. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolsManifestGenerator.cs +200 -200
  169. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringAdapters.cs +1467 -1467
  170. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringSafetyReloadGuard.cs +65 -65
  171. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityCopilotUpdateProjectSettings.cs +66 -66
  172. package/vendor/plugin/com.atelierai.unity.copilot/Plugins/ReflectorNet.dll +0 -0
  173. package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.Common.dll +0 -0
  174. package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.dll +0 -0
  175. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Converter/Json/Structures/EntityIdConverter.cs +120 -120
  176. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.cs +110 -110
  177. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.pre-Unity.6.5.cs +110 -110
  178. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/FileLogStorage.cs +547 -547
  179. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Build.cs +243 -243
  180. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Config.cs +175 -175
  181. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.cs +295 -295
  182. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginBuilder.cs +105 -105
  183. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.Static.cs +155 -155
  184. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.cs +59 -59
  185. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Utils/EnvironmentUtils.cs +368 -368
  186. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/AtomicApiTestFixtures.cs +99 -99
  187. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/TryModifyAtTests.cs +227 -227
  188. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AuthoringSafetyPilotTests.cs +1050 -1050
  189. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetLegacyMigrationTests.cs +304 -304
  190. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +4 -4
  191. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/BlacklistTypeTests.cs +416 -416
  192. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.cs +172 -172
  193. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.pre-Unity.6.5.cs +169 -169
  194. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.cs +182 -182
  195. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.pre-Unity.6.5.cs +179 -179
  196. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.cs +175 -175
  197. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.pre-Unity.6.5.cs +174 -174
  198. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.cs +171 -171
  199. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.pre-Unity.6.5.cs +170 -170
  200. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsCreateFolderTests.cs +243 -243
  201. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsMaterialTests.cs +101 -101
  202. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.cs +348 -348
  203. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.pre-Unity.6.5.cs +348 -348
  204. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsShaderTests.cs +194 -194
  205. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.cs +573 -573
  206. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.pre-Unity.6.5.cs +513 -513
  207. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.cs +154 -154
  208. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.pre-Unity.6.5.cs +154 -154
  209. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotGameViewTests.cs +164 -164
  210. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotSceneViewTests.cs +155 -155
  211. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolParameterTests.cs +56 -56
  212. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.cs +651 -651
  213. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.pre-Unity.6.5.cs +651 -651
  214. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ToolBatchExecutionIntegrationTests.cs +407 -407
  215. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs → UcoPluginTests.cs} +105 -105
  216. package/vendor/plugin/com.atelierai.unity.copilot/package.json +1 -1
  217. package/dist/commands/devops/login.d.ts +0 -2
  218. package/dist/commands/devops/login.js +0 -29
  219. package/dist/commands/devops/login.js.map +0 -1
  220. package/dist/commands/devops/setup-mcp.d.ts +0 -2
  221. package/dist/commands/devops/setup-mcp.js +0 -41
  222. package/dist/commands/devops/setup-mcp.js.map +0 -1
  223. package/dist/devops/commands-upstream/bootstrap-local.d.ts +0 -17
  224. package/dist/devops/commands-upstream/bootstrap-local.js +0 -87
  225. package/dist/devops/commands-upstream/bootstrap-local.js.map +0 -1
  226. package/dist/devops/commands-upstream/close.d.ts +0 -57
  227. package/dist/devops/commands-upstream/close.js +0 -188
  228. package/dist/devops/commands-upstream/close.js.map +0 -1
  229. package/dist/devops/commands-upstream/configure.d.ts +0 -2
  230. package/dist/devops/commands-upstream/configure.js +0 -87
  231. package/dist/devops/commands-upstream/configure.js.map +0 -1
  232. package/dist/devops/commands-upstream/create-project.d.ts +0 -2
  233. package/dist/devops/commands-upstream/create-project.js +0 -43
  234. package/dist/devops/commands-upstream/create-project.js.map +0 -1
  235. package/dist/devops/commands-upstream/install-plugin.d.ts +0 -2
  236. package/dist/devops/commands-upstream/install-plugin.js +0 -64
  237. package/dist/devops/commands-upstream/install-plugin.js.map +0 -1
  238. package/dist/devops/commands-upstream/install-unity.d.ts +0 -2
  239. package/dist/devops/commands-upstream/install-unity.js +0 -72
  240. package/dist/devops/commands-upstream/install-unity.js.map +0 -1
  241. package/dist/devops/commands-upstream/login.d.ts +0 -2
  242. package/dist/devops/commands-upstream/login.js +0 -33
  243. package/dist/devops/commands-upstream/login.js.map +0 -1
  244. package/dist/devops/commands-upstream/open.d.ts +0 -32
  245. package/dist/devops/commands-upstream/open.js +0 -282
  246. package/dist/devops/commands-upstream/open.js.map +0 -1
  247. package/dist/devops/commands-upstream/remove-plugin.d.ts +0 -2
  248. package/dist/devops/commands-upstream/remove-plugin.js +0 -41
  249. package/dist/devops/commands-upstream/remove-plugin.js.map +0 -1
  250. package/dist/devops/commands-upstream/run-system-tool.d.ts +0 -1
  251. package/dist/devops/commands-upstream/run-system-tool.js +0 -13
  252. package/dist/devops/commands-upstream/run-system-tool.js.map +0 -1
  253. package/dist/devops/commands-upstream/run-tool-builder.d.ts +0 -25
  254. package/dist/devops/commands-upstream/run-tool-builder.js +0 -125
  255. package/dist/devops/commands-upstream/run-tool-builder.js.map +0 -1
  256. package/dist/devops/commands-upstream/run-tool.d.ts +0 -1
  257. package/dist/devops/commands-upstream/run-tool.js +0 -13
  258. package/dist/devops/commands-upstream/run-tool.js.map +0 -1
  259. package/dist/devops/commands-upstream/setup-mcp.d.ts +0 -2
  260. package/dist/devops/commands-upstream/setup-mcp.js +0 -68
  261. package/dist/devops/commands-upstream/setup-mcp.js.map +0 -1
  262. package/dist/devops/commands-upstream/setup-skills.d.ts +0 -2
  263. package/dist/devops/commands-upstream/setup-skills.js +0 -167
  264. package/dist/devops/commands-upstream/setup-skills.js.map +0 -1
  265. package/dist/devops/commands-upstream/status.d.ts +0 -2
  266. package/dist/devops/commands-upstream/status.js +0 -87
  267. package/dist/devops/commands-upstream/status.js.map +0 -1
  268. package/dist/devops/commands-upstream/update.d.ts +0 -2
  269. package/dist/devops/commands-upstream/update.js +0 -77
  270. package/dist/devops/commands-upstream/update.js.map +0 -1
  271. package/dist/devops/commands-upstream/wait-for-ready.d.ts +0 -2
  272. package/dist/devops/commands-upstream/wait-for-ready.js +0 -93
  273. package/dist/devops/commands-upstream/wait-for-ready.js.map +0 -1
  274. package/dist/devops/lib/setup-mcp.d.ts +0 -35
  275. package/dist/devops/lib/setup-mcp.js +0 -177
  276. package/dist/devops/lib/setup-mcp.js.map +0 -1
  277. package/dist/devops/utils/cloud-login.d.ts +0 -7
  278. package/dist/devops/utils/cloud-login.js +0 -56
  279. package/dist/devops/utils/cloud-login.js.map +0 -1
  280. /package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs.meta → UcoPluginTests.cs.meta} +0 -0
@@ -1,372 +1,372 @@
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.Threading;
14
- using com.AtelierAI.Uco.Framework.Common.Model;
15
- using com.AtelierAI.Uco.Framework.Common.Utils;
16
- using com.IvanMurzak.ReflectorNet.Utils;
17
- using com.AtelierAI.Unity.Copilot.Editor.UI.Controls;
18
- using Microsoft.Extensions.Logging;
19
- using R3;
20
- using UnityEngine;
21
- using UnityEngine.UIElements;
22
- using static com.AtelierAI.Uco.Framework.Common.Consts.MCP.Server;
23
-
24
- namespace com.AtelierAI.Unity.Copilot.Editor.UI
25
- {
26
- public partial class MainWindowEditor
27
- {
28
- private void SetupMcpServerSection(VisualElement root)
29
- {
30
- var btnStartStop = root.Q<Button>("btnStartStopServer") ?? throw new InvalidOperationException("Server start/stop button not found.");
31
- var statusCircle = root.Q<VisualElement>("mcpServerStatusCircle") ?? throw new InvalidOperationException("Server status circle not found.");
32
- var statusLabel = root.Q<Label>("mcpServerLabel") ?? throw new InvalidOperationException("Server status label not found.");
33
-
34
- var timelinePointMcpServer = root.Q<VisualElement>("TimelinePointMcpServer");
35
- if (timelinePointMcpServer != null)
36
- timelinePointMcpServer.tooltip = Tooltip_McpServerTimelineLabel;
37
- statusCircle.tooltip = Tooltip_McpServerTimelineLabel;
38
- statusLabel.tooltip = Tooltip_McpServerTimelineLabel;
39
-
40
- Observable.CombineLatest(
41
- source1: CopilotServerManager.ServerStatus,
42
- source2: UnityCopilotPluginEditor.IsConnected,
43
- resultSelector: CombineCopilotServerStatus)
44
- .ThrottleLast(TimeSpan.FromMilliseconds(50))
45
- .ObserveOnCurrentSynchronizationContext()
46
- .Subscribe(status => FetchMcpServerData(status, btnStartStop, statusCircle, statusLabel))
47
- .AddTo(_disposables);
48
-
49
- btnStartStop.RegisterCallback<ClickEvent>(evt => HandleServerButton(btnStartStop, statusLabel));
50
-
51
- // server authorization configuration UI elements
52
- var labelAuthorizationToken = root.Q<Label>("labelAuthorizationToken");
53
- var segmentAuthorization = root.Q<VisualElement>("segmentAuthorization");
54
- var inputAuthorizationToken = root.Q<TextField>("inputAuthorizationToken");
55
- var tokenSection = root.Q<VisualElement>("tokenSection");
56
- var btnGenerateToken = root.Q<Button>("btnGenerateToken");
57
-
58
- if (segmentAuthorization == null || inputAuthorizationToken == null
59
- || tokenSection == null || btnGenerateToken == null)
60
- {
61
- Debug.LogError("One or more authorization UI elements not found in UXML: " +
62
- $"segmentAuthorization={segmentAuthorization != null}, " +
63
- $"inputAuthorizationToken={inputAuthorizationToken != null}, " +
64
- $"tokenSection={tokenSection != null}, " +
65
- $"btnGenerateToken={btnGenerateToken != null}");
66
- return;
67
- }
68
-
69
- var authControl = new SegmentedControl("none", "required");
70
- authControl.SetTooltips(Tooltip_ToggleAuthNone, Tooltip_ToggleAuthRequired);
71
- segmentAuthorization.Add(authControl);
72
-
73
- inputAuthorizationToken.isPasswordField = true;
74
- inputAuthorizationToken.RegisterCallback<KeyDownEvent>(evt =>
75
- {
76
- if (evt.keyCode == KeyCode.C && (evt.ctrlKey || evt.commandKey))
77
- {
78
- GUIUtility.systemCopyBuffer = inputAuthorizationToken.value;
79
- evt.StopPropagation();
80
- }
81
- });
82
-
83
- if (labelAuthorizationToken != null) labelAuthorizationToken.tooltip = Tooltip_LabelAuthorizationToken;
84
- btnGenerateToken.tooltip = Tooltip_BtnGenerateToken;
85
-
86
- var authOption = UnityCopilotPluginEditor.AuthOption;
87
- authControl.SetValueWithoutNotify(authOption == AuthOption.none ? 0 : 1);
88
- inputAuthorizationToken.SetValueWithoutNotify(UnityCopilotPluginEditor.Token ?? string.Empty);
89
- SetTokenFieldsVisible(inputAuthorizationToken, tokenSection, authOption == AuthOption.required);
90
-
91
- authControl.RegisterCallback<ChangeEvent<int>>(evt =>
92
- {
93
- if (evt.newValue == 0)
94
- {
95
- ApplyServerSettingAndRestart(() =>
96
- {
97
- UnityCopilotPluginEditor.AuthOption = AuthOption.none;
98
- });
99
- SetTokenFieldsVisible(inputAuthorizationToken, tokenSection, false);
100
- }
101
- else
102
- {
103
- ApplyServerSettingAndRestart(() =>
104
- {
105
- UnityCopilotPluginEditor.AuthOption = AuthOption.required;
106
- });
107
- SetTokenFieldsVisible(inputAuthorizationToken, tokenSection, true);
108
- }
109
- });
110
-
111
- inputAuthorizationToken.RegisterCallback<FocusOutEvent>(_ =>
112
- {
113
- var newToken = inputAuthorizationToken.value;
114
- if (newToken == UnityCopilotPluginEditor.Token)
115
- return;
116
-
117
- ApplyServerSettingAndRestart(() =>
118
- {
119
- UnityCopilotPluginEditor.Token = newToken;
120
- });
121
- });
122
-
123
- btnGenerateToken.RegisterCallback<ClickEvent>(_ =>
124
- {
125
- var newToken = UnityCopilotPlugin.GenerateToken();
126
- inputAuthorizationToken.SetValueWithoutNotify(newToken);
127
-
128
- ApplyServerSettingAndRestart(() =>
129
- {
130
- UnityCopilotPluginEditor.Token = newToken;
131
- });
132
- });
133
-
134
- // ── Network Safety (fail-closed by default) ─────────────────────────────
135
- // Build the UI programmatically and append it to the same flex column that
136
- // hosts tokenSection so we don't have to introduce a new UXML asset. The
137
- // three toggles map 1:1 to the static properties on UnityCopilotPluginEditor;
138
- // each change is persisted immediately so the next StartServer() call sees
139
- // the new state.
140
- BuildNetworkSafetySection(tokenSection.parent);
141
- }
142
-
143
- private static void BuildNetworkSafetySection(VisualElement parent)
144
- {
145
- if (parent == null) return;
146
- // If a previous CreateGUI cycle already added the section, recreate it idempotently
147
- // so the toggles always reflect the current persisted state.
148
- var existing = parent.Q<VisualElement>("networkSafetySection");
149
- if (existing != null) parent.Remove(existing);
150
-
151
- var section = new VisualElement { name = "networkSafetySection" };
152
- section.style.flexDirection = FlexDirection.Column;
153
- section.style.marginTop = 4;
154
- section.style.marginBottom = 2;
155
-
156
- var header = new Label("Network Safety");
157
- header.AddToClassList("section-desc");
158
- header.style.marginBottom = 2;
159
- header.tooltip =
160
- "Fail-closed defaults: by default the server only binds to localhost and " +
161
- "refuses to start on a non-loopback URL until you opt in here. Existing " +
162
- "configurations that already used a LAN address before this update were " +
163
- "auto-granted on first load so behaviour is preserved — a one-time warning " +
164
- "is written to the Editor console.";
165
- section.Add(header);
166
-
167
- var toggleAllowLan = new Toggle("Allow LAN Bind (HTTP)")
168
- {
169
- value = UnityCopilotPluginEditor.AllowLanBind,
170
- tooltip =
171
- "When OFF (safe default): the plugin refuses to start the server if " +
172
- "the Server URL points at 0.0.0.0, ::, or a non-loopback IP/hostname.\n\n" +
173
- "When ON: the plugin will start the server bound to whatever interface the " +
174
- "Server URL specifies. Other machines on your network may be able to reach " +
175
- "the server. Always pair this with a strong token."
176
- };
177
- toggleAllowLan.RegisterValueChangedCallback(evt =>
178
- {
179
- UnityCopilotPluginEditor.AllowLanBind = evt.newValue;
180
- UnityCopilotPluginEditor.Instance.Save();
181
- });
182
- section.Add(toggleAllowLan);
183
-
184
- var toggleAllowInsecure = new Toggle("Allow Insecure Remote HTTP")
185
- {
186
- value = UnityCopilotPluginEditor.AllowInsecureRemoteHttp,
187
- tooltip =
188
- "When OFF (safe default): the plugin logs a warning every time it emits an " +
189
- "AI-agent client configuration that points at a remote host over plain " +
190
- "http:// (no TLS).\n\n" +
191
- "When ON: the warning is silenced. Tokens and tool payloads sent over " +
192
- "plain HTTP are visible to anyone sniffing the network — only enable this " +
193
- "for trusted local networks where TLS is not available."
194
- };
195
- toggleAllowInsecure.RegisterValueChangedCallback(evt =>
196
- {
197
- UnityCopilotPluginEditor.AllowInsecureRemoteHttp = evt.newValue;
198
- UnityCopilotPluginEditor.Instance.Save();
199
- });
200
- section.Add(toggleAllowInsecure);
201
-
202
- var toggleForceToken = new Toggle("Force Token When LAN Bind")
203
- {
204
- value = UnityCopilotPluginEditor.ForceTokenWhenLanBind,
205
- tooltip =
206
- "When ON (safe default): enabling 'Allow LAN Bind' is not enough to start " +
207
- "the server — you must also set Authorization to 'required' and have a " +
208
- "non-empty token. Prevents accidental exposure of an unauthenticated " +
209
- "endpoint to the LAN.\n\n" +
210
- "When OFF: LAN-bound servers may run with auth=none. Not recommended."
211
- };
212
- toggleForceToken.RegisterValueChangedCallback(evt =>
213
- {
214
- UnityCopilotPluginEditor.ForceTokenWhenLanBind = evt.newValue;
215
- UnityCopilotPluginEditor.Instance.Save();
216
- });
217
- section.Add(toggleForceToken);
218
-
219
- parent.Add(section);
220
- }
221
-
222
- private void ApplyServerSettingAndRestart(Action applySetting)
223
- {
224
- var wasRunning = CopilotServerManager.IsRunning;
225
- applySetting();
226
- UnityCopilotPluginEditor.Instance.Save();
227
- RestartServerIfWasRunning(wasRunning);
228
- }
229
-
230
- internal static CopilotServerStatus CombineCopilotServerStatus(CopilotServerStatus status, bool isConnected)
231
- {
232
- if (isConnected && status != CopilotServerStatus.Running)
233
- return CopilotServerStatus.External;
234
-
235
- return status;
236
- }
237
-
238
- internal static string GetServerButtonText(CopilotServerStatus status) => status switch
239
- {
240
- CopilotServerStatus.Running => "Stop",
241
- CopilotServerStatus.Starting => "Starting...",
242
- CopilotServerStatus.Stopping => "Stopping...",
243
- CopilotServerStatus.External => "External",
244
- _ => "Start"
245
- };
246
-
247
- // The Node.js server exposes a single HTTP transport (REST + WebSocket), so the
248
- // status label no longer carries a transport-mode suffix.
249
- internal static string GetServerLabelText(CopilotServerStatus status) => status switch
250
- {
251
- CopilotServerStatus.Running => "Server: Running",
252
- CopilotServerStatus.Starting => "Server: Starting...",
253
- CopilotServerStatus.Stopping => "Server: Stopping...",
254
- CopilotServerStatus.External => "Server: External",
255
- _ => "Server"
256
- };
257
-
258
- internal static string GetServerStatusClass(CopilotServerStatus status) => status switch
259
- {
260
- CopilotServerStatus.Running => USS_Connected,
261
- CopilotServerStatus.Starting or CopilotServerStatus.Stopping => USS_Connecting,
262
- CopilotServerStatus.External => USS_External,
263
- _ => USS_Disconnected
264
- };
265
-
266
- internal static bool IsServerButtonEnabled(CopilotServerStatus status) =>
267
- status == CopilotServerStatus.Running || status == CopilotServerStatus.Stopped;
268
-
269
- private static void HandleServerButton(Button btnStartStop, Label statusLabel)
270
- {
271
- // Disable button immediately to prevent double-clicks
272
- btnStartStop.SetEnabled(false);
273
-
274
- try
275
- {
276
- if (CopilotServerManager.IsRunning)
277
- {
278
- // User is stopping the server - remember not to auto-start
279
- UnityCopilotPluginEditor.KeepServerRunning = false;
280
- UnityCopilotPluginEditor.Instance.Save();
281
- statusLabel.text = "Server: Stopping...";
282
- CopilotServerManager.StopServer();
283
- }
284
- else
285
- {
286
- // User is starting the server - remember to auto-start
287
- UnityCopilotPluginEditor.KeepServerRunning = true;
288
- UnityCopilotPluginEditor.Instance.Save();
289
- statusLabel.text = "Server: Starting...";
290
- CopilotServerManager.StartServer();
291
- }
292
- }
293
- catch
294
- {
295
- // Re-enable button on exception to avoid infinite lock
296
- btnStartStop.SetEnabled(true);
297
- throw;
298
- }
299
- }
300
-
301
- private long SetMcpServerData(UcoServerData? data, CopilotServerStatus status, Button btnStartStop, VisualElement statusCircle, Label statusLabel)
302
- {
303
- var version = Interlocked.Increment(ref _mcpServerDataVersion);
304
- if (Logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Trace))
305
- Logger.LogTrace("Setting server data: {status}, Data: {data}", status, data?.ToPrettyJson() ?? "null");
306
-
307
- btnStartStop.text = GetServerButtonText(status);
308
- var isStart = status == CopilotServerStatus.Stopped;
309
- btnStartStop.EnableInClassList("btn-primary", isStart);
310
- btnStartStop.EnableInClassList("btn-secondary", !isStart);
311
- btnStartStop.SetEnabled(IsServerButtonEnabled(status));
312
- statusLabel.text = GetServerLabelText(status);
313
- SetStatusIndicator(statusCircle, GetServerStatusClass(status));
314
- return version;
315
- }
316
-
317
- private void FetchMcpServerData(CopilotServerStatus status, Button btnStartStop, VisualElement statusCircle, Label statusLabel)
318
- {
319
- // Update UI immediately with current status; capture the version atomically so that
320
- // the async result can detect if a newer update has superseded it.
321
- var fetchVersion = SetMcpServerData(null, status, btnStartStop, statusCircle, statusLabel);
322
-
323
- // Then try to fetch additional data asynchronously
324
- var mcpPluginInstance = UnityCopilotPluginEditor.Instance.UcoPluginInstance;
325
- if (mcpPluginInstance == null)
326
- {
327
- Logger.LogDebug("Cannot fetch server data: UcoPluginInstance is null");
328
- return;
329
- }
330
-
331
- var mcpManagerHub = mcpPluginInstance.UcoManagerHub;
332
- if (mcpManagerHub == null)
333
- {
334
- Logger.LogDebug("Cannot fetch server data: UcoManagerHub is null");
335
- return;
336
- }
337
-
338
- var task = mcpManagerHub.GetMcpServerData();
339
- if (task == null)
340
- {
341
- Logger.LogDebug("Cannot fetch server data: GetMcpServerData returned null");
342
- return;
343
- }
344
-
345
- task.ContinueWith(t =>
346
- {
347
- if (Interlocked.Read(ref _mcpServerDataVersion) != fetchVersion)
348
- {
349
- Logger.LogTrace("Skipping server data update because a newer update was applied at {time}",
350
- DateTime.UtcNow);
351
- return;
352
- }
353
- MainThread.Instance.Run(() =>
354
- {
355
- // Second check: close the TOCTOU window between the thread-pool check above
356
- // and the main-thread callback execution.
357
- if (Interlocked.Read(ref _mcpServerDataVersion) != fetchVersion)
358
- return;
359
- if (t.IsCompletedSuccessfully)
360
- {
361
- var data = t.Result;
362
- SetMcpServerData(data, status, btnStartStop, statusCircle, statusLabel);
363
- }
364
- else if (t.IsFaulted)
365
- {
366
- Logger.LogDebug("Failed to fetch server data: {error}", t.Exception?.Message ?? "Unknown error");
367
- }
368
- });
369
- });
370
- }
371
- }
372
- }
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.Threading;
14
+ using com.AtelierAI.Uco.Framework.Common.Model;
15
+ using com.AtelierAI.Uco.Framework.Common.Utils;
16
+ using com.IvanMurzak.ReflectorNet.Utils;
17
+ using com.AtelierAI.Unity.Copilot.Editor.UI.Controls;
18
+ using Microsoft.Extensions.Logging;
19
+ using R3;
20
+ using UnityEngine;
21
+ using UnityEngine.UIElements;
22
+ using static com.AtelierAI.Uco.Framework.Common.Consts.Uco.Server;
23
+
24
+ namespace com.AtelierAI.Unity.Copilot.Editor.UI
25
+ {
26
+ public partial class MainWindowEditor
27
+ {
28
+ private void SetupServerSection(VisualElement root)
29
+ {
30
+ var btnStartStop = root.Q<Button>("btnStartStopServer") ?? throw new InvalidOperationException("Server start/stop button not found.");
31
+ var statusCircle = root.Q<VisualElement>("mcpServerStatusCircle") ?? throw new InvalidOperationException("Server status circle not found.");
32
+ var statusLabel = root.Q<Label>("mcpServerLabel") ?? throw new InvalidOperationException("Server status label not found.");
33
+
34
+ var timelinePointServer = root.Q<VisualElement>("TimelinePointMcpServer");
35
+ if (timelinePointServer != null)
36
+ timelinePointServer.tooltip = Tooltip_ServerTimelineLabel;
37
+ statusCircle.tooltip = Tooltip_ServerTimelineLabel;
38
+ statusLabel.tooltip = Tooltip_ServerTimelineLabel;
39
+
40
+ Observable.CombineLatest(
41
+ source1: CopilotServerManager.ServerStatus,
42
+ source2: UnityCopilotPluginEditor.IsConnected,
43
+ resultSelector: CombineCopilotServerStatus)
44
+ .ThrottleLast(TimeSpan.FromMilliseconds(50))
45
+ .ObserveOnCurrentSynchronizationContext()
46
+ .Subscribe(status => FetchServerData(status, btnStartStop, statusCircle, statusLabel))
47
+ .AddTo(_disposables);
48
+
49
+ btnStartStop.RegisterCallback<ClickEvent>(evt => HandleServerButton(btnStartStop, statusLabel));
50
+
51
+ // server authorization configuration UI elements
52
+ var labelAuthorizationToken = root.Q<Label>("labelAuthorizationToken");
53
+ var segmentAuthorization = root.Q<VisualElement>("segmentAuthorization");
54
+ var inputAuthorizationToken = root.Q<TextField>("inputAuthorizationToken");
55
+ var tokenSection = root.Q<VisualElement>("tokenSection");
56
+ var btnGenerateToken = root.Q<Button>("btnGenerateToken");
57
+
58
+ if (segmentAuthorization == null || inputAuthorizationToken == null
59
+ || tokenSection == null || btnGenerateToken == null)
60
+ {
61
+ Debug.LogError("One or more authorization UI elements not found in UXML: " +
62
+ $"segmentAuthorization={segmentAuthorization != null}, " +
63
+ $"inputAuthorizationToken={inputAuthorizationToken != null}, " +
64
+ $"tokenSection={tokenSection != null}, " +
65
+ $"btnGenerateToken={btnGenerateToken != null}");
66
+ return;
67
+ }
68
+
69
+ var authControl = new SegmentedControl("none", "required");
70
+ authControl.SetTooltips(Tooltip_ToggleAuthNone, Tooltip_ToggleAuthRequired);
71
+ segmentAuthorization.Add(authControl);
72
+
73
+ inputAuthorizationToken.isPasswordField = true;
74
+ inputAuthorizationToken.RegisterCallback<KeyDownEvent>(evt =>
75
+ {
76
+ if (evt.keyCode == KeyCode.C && (evt.ctrlKey || evt.commandKey))
77
+ {
78
+ GUIUtility.systemCopyBuffer = inputAuthorizationToken.value;
79
+ evt.StopPropagation();
80
+ }
81
+ });
82
+
83
+ if (labelAuthorizationToken != null) labelAuthorizationToken.tooltip = Tooltip_LabelAuthorizationToken;
84
+ btnGenerateToken.tooltip = Tooltip_BtnGenerateToken;
85
+
86
+ var authOption = UnityCopilotPluginEditor.AuthOption;
87
+ authControl.SetValueWithoutNotify(authOption == AuthOption.none ? 0 : 1);
88
+ inputAuthorizationToken.SetValueWithoutNotify(UnityCopilotPluginEditor.Token ?? string.Empty);
89
+ SetTokenFieldsVisible(inputAuthorizationToken, tokenSection, authOption == AuthOption.required);
90
+
91
+ authControl.RegisterCallback<ChangeEvent<int>>(evt =>
92
+ {
93
+ if (evt.newValue == 0)
94
+ {
95
+ ApplyServerSettingAndRestart(() =>
96
+ {
97
+ UnityCopilotPluginEditor.AuthOption = AuthOption.none;
98
+ });
99
+ SetTokenFieldsVisible(inputAuthorizationToken, tokenSection, false);
100
+ }
101
+ else
102
+ {
103
+ ApplyServerSettingAndRestart(() =>
104
+ {
105
+ UnityCopilotPluginEditor.AuthOption = AuthOption.required;
106
+ });
107
+ SetTokenFieldsVisible(inputAuthorizationToken, tokenSection, true);
108
+ }
109
+ });
110
+
111
+ inputAuthorizationToken.RegisterCallback<FocusOutEvent>(_ =>
112
+ {
113
+ var newToken = inputAuthorizationToken.value;
114
+ if (newToken == UnityCopilotPluginEditor.Token)
115
+ return;
116
+
117
+ ApplyServerSettingAndRestart(() =>
118
+ {
119
+ UnityCopilotPluginEditor.Token = newToken;
120
+ });
121
+ });
122
+
123
+ btnGenerateToken.RegisterCallback<ClickEvent>(_ =>
124
+ {
125
+ var newToken = UnityCopilotPlugin.GenerateToken();
126
+ inputAuthorizationToken.SetValueWithoutNotify(newToken);
127
+
128
+ ApplyServerSettingAndRestart(() =>
129
+ {
130
+ UnityCopilotPluginEditor.Token = newToken;
131
+ });
132
+ });
133
+
134
+ // ── Network Safety (fail-closed by default) ─────────────────────────────
135
+ // Build the UI programmatically and append it to the same flex column that
136
+ // hosts tokenSection so we don't have to introduce a new UXML asset. The
137
+ // three toggles map 1:1 to the static properties on UnityCopilotPluginEditor;
138
+ // each change is persisted immediately so the next StartServer() call sees
139
+ // the new state.
140
+ BuildNetworkSafetySection(tokenSection.parent);
141
+ }
142
+
143
+ private static void BuildNetworkSafetySection(VisualElement parent)
144
+ {
145
+ if (parent == null) return;
146
+ // If a previous CreateGUI cycle already added the section, recreate it idempotently
147
+ // so the toggles always reflect the current persisted state.
148
+ var existing = parent.Q<VisualElement>("networkSafetySection");
149
+ if (existing != null) parent.Remove(existing);
150
+
151
+ var section = new VisualElement { name = "networkSafetySection" };
152
+ section.style.flexDirection = FlexDirection.Column;
153
+ section.style.marginTop = 4;
154
+ section.style.marginBottom = 2;
155
+
156
+ var header = new Label("Network Safety");
157
+ header.AddToClassList("section-desc");
158
+ header.style.marginBottom = 2;
159
+ header.tooltip =
160
+ "Fail-closed defaults: by default the server only binds to localhost and " +
161
+ "refuses to start on a non-loopback URL until you opt in here. Existing " +
162
+ "configurations that already used a LAN address before this update were " +
163
+ "auto-granted on first load so behaviour is preserved — a one-time warning " +
164
+ "is written to the Editor console.";
165
+ section.Add(header);
166
+
167
+ var toggleAllowLan = new Toggle("Allow LAN Bind (HTTP)")
168
+ {
169
+ value = UnityCopilotPluginEditor.AllowLanBind,
170
+ tooltip =
171
+ "When OFF (safe default): the plugin refuses to start the server if " +
172
+ "the Server URL points at 0.0.0.0, ::, or a non-loopback IP/hostname.\n\n" +
173
+ "When ON: the plugin will start the server bound to whatever interface the " +
174
+ "Server URL specifies. Other machines on your network may be able to reach " +
175
+ "the server. Always pair this with a strong token."
176
+ };
177
+ toggleAllowLan.RegisterValueChangedCallback(evt =>
178
+ {
179
+ UnityCopilotPluginEditor.AllowLanBind = evt.newValue;
180
+ UnityCopilotPluginEditor.Instance.Save();
181
+ });
182
+ section.Add(toggleAllowLan);
183
+
184
+ var toggleAllowInsecure = new Toggle("Allow Insecure Remote HTTP")
185
+ {
186
+ value = UnityCopilotPluginEditor.AllowInsecureRemoteHttp,
187
+ tooltip =
188
+ "When OFF (safe default): the plugin logs a warning every time it emits an " +
189
+ "AI-agent client configuration that points at a remote host over plain " +
190
+ "http:// (no TLS).\n\n" +
191
+ "When ON: the warning is silenced. Tokens and tool payloads sent over " +
192
+ "plain HTTP are visible to anyone sniffing the network — only enable this " +
193
+ "for trusted local networks where TLS is not available."
194
+ };
195
+ toggleAllowInsecure.RegisterValueChangedCallback(evt =>
196
+ {
197
+ UnityCopilotPluginEditor.AllowInsecureRemoteHttp = evt.newValue;
198
+ UnityCopilotPluginEditor.Instance.Save();
199
+ });
200
+ section.Add(toggleAllowInsecure);
201
+
202
+ var toggleForceToken = new Toggle("Force Token When LAN Bind")
203
+ {
204
+ value = UnityCopilotPluginEditor.ForceTokenWhenLanBind,
205
+ tooltip =
206
+ "When ON (safe default): enabling 'Allow LAN Bind' is not enough to start " +
207
+ "the server — you must also set Authorization to 'required' and have a " +
208
+ "non-empty token. Prevents accidental exposure of an unauthenticated " +
209
+ "endpoint to the LAN.\n\n" +
210
+ "When OFF: LAN-bound servers may run with auth=none. Not recommended."
211
+ };
212
+ toggleForceToken.RegisterValueChangedCallback(evt =>
213
+ {
214
+ UnityCopilotPluginEditor.ForceTokenWhenLanBind = evt.newValue;
215
+ UnityCopilotPluginEditor.Instance.Save();
216
+ });
217
+ section.Add(toggleForceToken);
218
+
219
+ parent.Add(section);
220
+ }
221
+
222
+ private void ApplyServerSettingAndRestart(Action applySetting)
223
+ {
224
+ var wasRunning = CopilotServerManager.IsRunning;
225
+ applySetting();
226
+ UnityCopilotPluginEditor.Instance.Save();
227
+ RestartServerIfWasRunning(wasRunning);
228
+ }
229
+
230
+ internal static CopilotServerStatus CombineCopilotServerStatus(CopilotServerStatus status, bool isConnected)
231
+ {
232
+ if (isConnected && status != CopilotServerStatus.Running)
233
+ return CopilotServerStatus.External;
234
+
235
+ return status;
236
+ }
237
+
238
+ internal static string GetServerButtonText(CopilotServerStatus status) => status switch
239
+ {
240
+ CopilotServerStatus.Running => "Stop",
241
+ CopilotServerStatus.Starting => "Starting...",
242
+ CopilotServerStatus.Stopping => "Stopping...",
243
+ CopilotServerStatus.External => "External",
244
+ _ => "Start"
245
+ };
246
+
247
+ // The Node.js server exposes a single HTTP transport (REST + WebSocket), so the
248
+ // status label no longer carries a transport-mode suffix.
249
+ internal static string GetServerLabelText(CopilotServerStatus status) => status switch
250
+ {
251
+ CopilotServerStatus.Running => "Server: Running",
252
+ CopilotServerStatus.Starting => "Server: Starting...",
253
+ CopilotServerStatus.Stopping => "Server: Stopping...",
254
+ CopilotServerStatus.External => "Server: External",
255
+ _ => "Server"
256
+ };
257
+
258
+ internal static string GetServerStatusClass(CopilotServerStatus status) => status switch
259
+ {
260
+ CopilotServerStatus.Running => USS_Connected,
261
+ CopilotServerStatus.Starting or CopilotServerStatus.Stopping => USS_Connecting,
262
+ CopilotServerStatus.External => USS_External,
263
+ _ => USS_Disconnected
264
+ };
265
+
266
+ internal static bool IsServerButtonEnabled(CopilotServerStatus status) =>
267
+ status == CopilotServerStatus.Running || status == CopilotServerStatus.Stopped;
268
+
269
+ private static void HandleServerButton(Button btnStartStop, Label statusLabel)
270
+ {
271
+ // Disable button immediately to prevent double-clicks
272
+ btnStartStop.SetEnabled(false);
273
+
274
+ try
275
+ {
276
+ if (CopilotServerManager.IsRunning)
277
+ {
278
+ // User is stopping the server - remember not to auto-start
279
+ UnityCopilotPluginEditor.KeepServerRunning = false;
280
+ UnityCopilotPluginEditor.Instance.Save();
281
+ statusLabel.text = "Server: Stopping...";
282
+ CopilotServerManager.StopServer();
283
+ }
284
+ else
285
+ {
286
+ // User is starting the server - remember to auto-start
287
+ UnityCopilotPluginEditor.KeepServerRunning = true;
288
+ UnityCopilotPluginEditor.Instance.Save();
289
+ statusLabel.text = "Server: Starting...";
290
+ CopilotServerManager.StartServer();
291
+ }
292
+ }
293
+ catch
294
+ {
295
+ // Re-enable button on exception to avoid infinite lock
296
+ btnStartStop.SetEnabled(true);
297
+ throw;
298
+ }
299
+ }
300
+
301
+ private long SetServerData(UcoServerData? data, CopilotServerStatus status, Button btnStartStop, VisualElement statusCircle, Label statusLabel)
302
+ {
303
+ var version = Interlocked.Increment(ref _serverDataVersion);
304
+ if (Logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Trace))
305
+ Logger.LogTrace("Setting server data: {status}, Data: {data}", status, data?.ToPrettyJson() ?? "null");
306
+
307
+ btnStartStop.text = GetServerButtonText(status);
308
+ var isStart = status == CopilotServerStatus.Stopped;
309
+ btnStartStop.EnableInClassList("btn-primary", isStart);
310
+ btnStartStop.EnableInClassList("btn-secondary", !isStart);
311
+ btnStartStop.SetEnabled(IsServerButtonEnabled(status));
312
+ statusLabel.text = GetServerLabelText(status);
313
+ SetStatusIndicator(statusCircle, GetServerStatusClass(status));
314
+ return version;
315
+ }
316
+
317
+ private void FetchServerData(CopilotServerStatus status, Button btnStartStop, VisualElement statusCircle, Label statusLabel)
318
+ {
319
+ // Update UI immediately with current status; capture the version atomically so that
320
+ // the async result can detect if a newer update has superseded it.
321
+ var fetchVersion = SetServerData(null, status, btnStartStop, statusCircle, statusLabel);
322
+
323
+ // Then try to fetch additional data asynchronously
324
+ var ucoPluginInstance = UnityCopilotPluginEditor.Instance.UcoPluginInstance;
325
+ if (ucoPluginInstance == null)
326
+ {
327
+ Logger.LogDebug("Cannot fetch server data: UcoPluginInstance is null");
328
+ return;
329
+ }
330
+
331
+ var pluginManagerHub = ucoPluginInstance.UcoManagerHub;
332
+ if (pluginManagerHub == null)
333
+ {
334
+ Logger.LogDebug("Cannot fetch server data: UcoManagerHub is null");
335
+ return;
336
+ }
337
+
338
+ var task = pluginManagerHub.GetServerData();
339
+ if (task == null)
340
+ {
341
+ Logger.LogDebug("Cannot fetch server data: GetServerData returned null");
342
+ return;
343
+ }
344
+
345
+ task.ContinueWith(t =>
346
+ {
347
+ if (Interlocked.Read(ref _serverDataVersion) != fetchVersion)
348
+ {
349
+ Logger.LogTrace("Skipping server data update because a newer update was applied at {time}",
350
+ DateTime.UtcNow);
351
+ return;
352
+ }
353
+ MainThread.Instance.Run(() =>
354
+ {
355
+ // Second check: close the TOCTOU window between the thread-pool check above
356
+ // and the main-thread callback execution.
357
+ if (Interlocked.Read(ref _serverDataVersion) != fetchVersion)
358
+ return;
359
+ if (t.IsCompletedSuccessfully)
360
+ {
361
+ var data = t.Result;
362
+ SetServerData(data, status, btnStartStop, statusCircle, statusLabel);
363
+ }
364
+ else if (t.IsFaulted)
365
+ {
366
+ Logger.LogDebug("Failed to fetch server data: {error}", t.Exception?.Message ?? "Unknown error");
367
+ }
368
+ });
369
+ });
370
+ }
371
+ }
372
+ }