@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,368 +1,368 @@
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.Collections.Generic;
14
- using com.AtelierAI.Uco.Framework.Common.Utils;
15
- using com.AtelierAI.Unity.Copilot.Utils;
16
- using Microsoft.Extensions.Logging;
17
- using static com.AtelierAI.Uco.Framework.Common.Consts.MCP.Server;
18
-
19
- namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
20
- {
21
- /// <summary>
22
- /// Loads MCP plugin configuration from layered sources and (optionally) applies
23
- /// runtime overrides from environment variables and process command-line arguments.
24
- ///
25
- /// Priority (highest wins):
26
- /// 1. Process command-line flags (e.g. <c>--url</c>, <c>--token</c>, <c>--auth</c>,
27
- /// or any <c>--UNITY_MCP_*</c> variant)
28
- /// 2. Process environment variables (<c>UNITY_MCP_*</c>)
29
- /// 3. On-disk config (<c>UserSettings/AI-Game-Developer-Config.json</c>)
30
- /// 4. Built-in defaults
31
- ///
32
- /// Overrides applied via env vars / flags are NEVER persisted back to disk —
33
- /// they are runtime-only. The <see cref="OverrideRecord"/> returned by
34
- /// <see cref="ApplyEnvironmentOverrides"/> captures both the disk-baseline values
35
- /// and the override values so that the editor's Save() flow can restore the
36
- /// baseline before serializing. See <c>UnityCopilotPluginEditor.Save</c>.
37
- /// </summary>
38
- public static class EnvironmentUtils
39
- {
40
- static readonly ILogger _logger = UnityLoggerFactory.LoggerFactory.CreateLogger(nameof(EnvironmentUtils));
41
-
42
- // Environment variable names for MCP connection overrides.
43
- public const string EnvHost = "UNITY_MCP_HOST";
44
- public const string EnvKeepConnected = "UNITY_MCP_KEEP_CONNECTED";
45
- public const string EnvAuthOption = "UNITY_MCP_AUTH_OPTION";
46
- public const string EnvToken = "UNITY_MCP_TOKEN";
47
- public const string EnvTools = "UNITY_MCP_TOOLS";
48
- public const string EnvStartServer = "UNITY_MCP_START_SERVER";
49
- public const string EnvTransport = "UNITY_MCP_TRANSPORT";
50
- public const string EnvConnectionMode = "UNITY_MCP_CONNECTION_MODE";
51
-
52
- // Short flag aliases recognised by the in-plugin command-line parser.
53
- // The CLI tool already translates these to the equivalent env vars before
54
- // launching Unity, but the plugin still parses them directly so
55
- // out-of-band invocations (manual editor launch, IDE config, etc.) work.
56
- public const string FlagUrl = "url";
57
- public const string FlagToken = "token";
58
- public const string FlagAuth = "auth";
59
-
60
- // Field-name keys used by OverrideRecord to track which fields were overridden
61
- // by env/flags so the Save flow can restore disk-baseline values before writing.
62
- public const string FieldHost = nameof(UnityCopilotPlugin.UnityConnectionConfig.LocalHost);
63
- public const string FieldKeepConnected = nameof(UnityCopilotPlugin.UnityConnectionConfig.KeepConnected);
64
- public const string FieldAuthOption = nameof(UnityCopilotPlugin.UnityConnectionConfig.AuthOption);
65
- public const string FieldLocalToken = nameof(UnityCopilotPlugin.UnityConnectionConfig.LocalToken);
66
- public const string FieldTools = nameof(UnityCopilotPlugin.UnityConnectionConfig.EnabledToolsOverride);
67
- public const string FieldStartServer = nameof(UnityCopilotPlugin.UnityConnectionConfig.KeepServerRunning);
68
- public const string FieldTransport = nameof(UnityCopilotPlugin.UnityConnectionConfig.TransportMethod);
69
- public const string FieldConnectionMode = nameof(UnityCopilotPlugin.UnityConnectionConfig.ConnectionMode);
70
-
71
- /// <summary>
72
- /// Captures, per overridden field, the disk-baseline value (what was read from JSON)
73
- /// and the runtime override value applied on top. Allows <c>Save()</c> to round-trip
74
- /// the baseline to disk while keeping the runtime override on the in-memory config.
75
- /// Empty when no env/flag overrides were detected.
76
- /// </summary>
77
- public sealed class OverrideRecord
78
- {
79
- readonly Dictionary<string, object?> _baselineValues = new();
80
- readonly Dictionary<string, object?> _overrideValues = new();
81
-
82
- public IReadOnlyDictionary<string, object?> BaselineValues => _baselineValues;
83
- public IReadOnlyDictionary<string, object?> OverrideValues => _overrideValues;
84
-
85
- public bool HasAny => _baselineValues.Count > 0;
86
- public bool Contains(string fieldName) => _baselineValues.ContainsKey(fieldName);
87
-
88
- internal void Track(string fieldName, object? baselineValue, object? overrideValue)
89
- {
90
- _baselineValues[fieldName] = baselineValue;
91
- _overrideValues[fieldName] = overrideValue;
92
- }
93
- }
94
-
95
- /// <summary>
96
- /// Checks if the current environment is a CI environment.
97
- /// </summary>
98
- public static bool IsCi()
99
- {
100
- var commandLineArgs = ArgsUtils.ParseCommandLineArguments();
101
-
102
- var ci = commandLineArgs.GetValueOrDefault("CI") ?? Environment.GetEnvironmentVariable("CI");
103
- var gha = commandLineArgs.GetValueOrDefault("GITHUB_ACTIONS") ?? Environment.GetEnvironmentVariable("GITHUB_ACTIONS");
104
- var az = commandLineArgs.GetValueOrDefault("TF_BUILD") ?? Environment.GetEnvironmentVariable("TF_BUILD"); // Azure Pipelines
105
-
106
- return string.Equals(ci?.Trim()?.Trim('"'), "true", StringComparison.OrdinalIgnoreCase)
107
- || string.Equals(gha?.Trim()?.Trim('"'), "true", StringComparison.OrdinalIgnoreCase)
108
- || string.Equals(az?.Trim()?.Trim('"'), "true", StringComparison.OrdinalIgnoreCase);
109
- }
110
-
111
- /// <summary>
112
- /// Checks if the Editor was launched with -batchmode (COCli-13).
113
- /// Batchmode launches without a configured server (offline builds,
114
- /// command-line automation) must not run the connection retry loop —
115
- /// its warnings would pollute BuildReport output.
116
- /// </summary>
117
- public static bool IsBatchMode()
118
- => IsBatchMode(UnityEngine.Application.isBatchMode, ArgsUtils.ParseCommandLineArguments());
119
-
120
- /// <summary>Test-friendly overload taking the parsed command-line args.</summary>
121
- public static bool IsBatchMode(
122
- bool applicationIsBatchMode,
123
- IReadOnlyDictionary<string, string> commandLineArgs)
124
- => applicationIsBatchMode || commandLineArgs.ContainsKey("batchmode");
125
-
126
- /// <summary>
127
- /// Applies environment-variable and command-line-argument overrides to the given config.
128
- /// Args (highest priority) override env vars, env vars override the disk-baseline values
129
- /// already present on <paramref name="config"/>. Returns an <see cref="OverrideRecord"/>
130
- /// that captures the disk-baseline value for each field that was overridden.
131
- /// </summary>
132
- public static OverrideRecord ApplyEnvironmentOverrides(UnityCopilotPlugin.UnityConnectionConfig config)
133
- {
134
- var args = ArgsUtils.ParseCommandLineArguments();
135
- return ApplyEnvironmentOverrides(config, args, Environment.GetEnvironmentVariable);
136
- }
137
-
138
- /// <summary>
139
- /// Test-friendly overload. <paramref name="argReader"/> is the parsed command-line
140
- /// arg dictionary (keys without leading dashes); <paramref name="envReader"/> resolves
141
- /// environment variables. Either may be empty / always-null to disable that source.
142
- /// </summary>
143
- public static OverrideRecord ApplyEnvironmentOverrides(
144
- UnityCopilotPlugin.UnityConnectionConfig config,
145
- IReadOnlyDictionary<string, string> argReader,
146
- Func<string, string?> envReader)
147
- {
148
- if (config == null) throw new ArgumentNullException(nameof(config));
149
- if (argReader == null) throw new ArgumentNullException(nameof(argReader));
150
- if (envReader == null) throw new ArgumentNullException(nameof(envReader));
151
-
152
- var record = new OverrideRecord();
153
-
154
- // Resolve a value with priority: short-flag-alias (highest) > UNITY_MCP_* env-style flag > env var.
155
- // Returns null if no source provided a non-empty value.
156
- string? Resolve(string envKey, string? flagAlias)
157
- {
158
- if (!string.IsNullOrEmpty(flagAlias)
159
- && argReader.TryGetValue(flagAlias, out var flagValue)
160
- && !string.IsNullOrWhiteSpace(flagValue))
161
- {
162
- return flagValue;
163
- }
164
- if (argReader.TryGetValue(envKey, out var envFlagValue)
165
- && !string.IsNullOrWhiteSpace(envFlagValue))
166
- {
167
- return envFlagValue;
168
- }
169
- var envValue = envReader(envKey);
170
- if (!string.IsNullOrWhiteSpace(envValue))
171
- return envValue;
172
- return null;
173
- }
174
-
175
- string Sanitize(string raw) => raw.Trim().Trim('"');
176
-
177
- // UNITY_MCP_HOST / --url override the local server host.
178
- string? sanitizedHost = null;
179
- var rawHost = Resolve(EnvHost, FlagUrl);
180
- if (rawHost != null)
181
- {
182
- var host = Sanitize(rawHost).TrimEnd('/');
183
- if (host.Length > 0)
184
- {
185
- sanitizedHost = host;
186
- if (!string.Equals(host, config.LocalHost, StringComparison.Ordinal))
187
- {
188
- record.Track(FieldHost, config.LocalHost, host);
189
- config.LocalHost = host;
190
- _logger.LogInformation("[MCP] Override: {Key}={Value}", FieldHost, host);
191
- }
192
- }
193
- }
194
-
195
- // Loopback URLs without an explicit mode infer Custom (worktree / local-dev).
196
- // Remote URLs without an explicit mode leave the disk-baseline ConnectionMode untouched.
197
- var rawMode = Resolve(EnvConnectionMode, flagAlias: null);
198
- ConnectionMode? targetMode = null;
199
- if (rawMode != null && Enum.TryParse<ConnectionMode>(Sanitize(rawMode), ignoreCase: true, out var explicitMode))
200
- {
201
- targetMode = explicitMode;
202
- }
203
- else if (sanitizedHost != null && IsLoopbackUrl(sanitizedHost))
204
- {
205
- targetMode = ConnectionMode.Custom;
206
- }
207
- if (targetMode.HasValue && targetMode.Value != config.ConnectionMode)
208
- {
209
- record.Track(FieldConnectionMode, config.ConnectionMode, targetMode.Value);
210
- config.ConnectionMode = targetMode.Value;
211
- _logger.LogInformation("[MCP] Override: {Key}={Value}", FieldConnectionMode, targetMode.Value);
212
- }
213
-
214
- var rawKeep = Resolve(EnvKeepConnected, flagAlias: null);
215
- if (rawKeep != null && bool.TryParse(Sanitize(rawKeep), out var keep) && keep != config.KeepConnected)
216
- {
217
- record.Track(FieldKeepConnected, config.KeepConnected, keep);
218
- config.KeepConnected = keep;
219
- _logger.LogInformation("[MCP] Override: {Key}={Value}", EnvKeepConnected, keep);
220
- }
221
-
222
- var rawAuth = Resolve(EnvAuthOption, FlagAuth);
223
- if (rawAuth != null
224
- && Enum.TryParse<AuthOption>(Sanitize(rawAuth), ignoreCase: true, out var ao)
225
- && ao != config.AuthOption)
226
- {
227
- record.Track(FieldAuthOption, config.AuthOption, ao);
228
- config.AuthOption = ao;
229
- _logger.LogInformation("[MCP] Override: {Key}={Value}", EnvAuthOption, ao);
230
- }
231
-
232
- // We track the specific
233
- // backing field rather than the abstract Token property because only the backing
234
- // fields are serialised — restoring the baseline must target the same field that
235
- // was clobbered.
236
- var rawToken = Resolve(EnvToken, FlagToken);
237
- if (rawToken != null)
238
- {
239
- var token = Sanitize(rawToken);
240
- if (!string.Equals(token, config.LocalToken, StringComparison.Ordinal))
241
- {
242
- record.Track(FieldLocalToken, config.LocalToken, token);
243
- config.LocalToken = token;
244
- _logger.LogInformation("[MCP] Override: {Key}=*** (LocalToken)", EnvToken);
245
- }
246
- }
247
-
248
- var rawTransport = Resolve(EnvTransport, flagAlias: null);
249
- if (rawTransport != null
250
- && Enum.TryParse<TransportMethod>(Sanitize(rawTransport), ignoreCase: true, out var tm)
251
- && tm != config.TransportMethod)
252
- {
253
- record.Track(FieldTransport, config.TransportMethod, tm);
254
- config.TransportMethod = tm;
255
- _logger.LogInformation("[MCP] Override: {Key}={Value}", EnvTransport, tm);
256
- }
257
-
258
- var rawStart = Resolve(EnvStartServer, flagAlias: null);
259
- if (rawStart != null && bool.TryParse(Sanitize(rawStart), out var ss) && ss != config.KeepServerRunning)
260
- {
261
- record.Track(FieldStartServer, config.KeepServerRunning, ss);
262
- config.KeepServerRunning = ss;
263
- _logger.LogInformation("[MCP] Override: {Key}={Value}", EnvStartServer, ss);
264
- }
265
-
266
- // EnabledToolsOverride is [JsonIgnore] so it is never persisted regardless of the
267
- // baseline-restoration logic; we still track it for completeness.
268
- var rawTools = Resolve(EnvTools, flagAlias: null);
269
- if (rawTools != null)
270
- {
271
- var ids = rawTools.Split(',', StringSplitOptions.RemoveEmptyEntries);
272
- var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
273
- var trimmed = new List<string>(ids.Length);
274
- foreach (var id in ids)
275
- {
276
- var value = Sanitize(id);
277
- if (!string.IsNullOrWhiteSpace(value) && seen.Add(value))
278
- trimmed.Add(value);
279
- }
280
- record.Track(FieldTools, config.EnabledToolsOverride, trimmed);
281
- config.EnabledToolsOverride = trimmed;
282
- _logger.LogInformation("[MCP] Override: {Key}={Value}", EnvTools, rawTools.Trim());
283
- }
284
-
285
- return record;
286
- }
287
-
288
- /// <summary>
289
- /// Applies the BaselineValues from <paramref name="record"/> to <paramref name="config"/>
290
- /// (i.e. reverses runtime overrides so the in-memory config reflects what is on disk).
291
- /// Used by the editor's Save() flow to ensure runtime-only overrides are not persisted.
292
- /// </summary>
293
- public static void ApplyBaseline(UnityCopilotPlugin.UnityConnectionConfig config, OverrideRecord record)
294
- {
295
- if (config == null) throw new ArgumentNullException(nameof(config));
296
- if (record == null) throw new ArgumentNullException(nameof(record));
297
- ApplyValues(config, record.BaselineValues);
298
- }
299
-
300
- /// <summary>
301
- /// Re-applies the OverrideValues from <paramref name="record"/> to <paramref name="config"/>
302
- /// (i.e. restores runtime overrides after a temporary baseline-restore).
303
- /// </summary>
304
- public static void ApplyOverrides(UnityCopilotPlugin.UnityConnectionConfig config, OverrideRecord record)
305
- {
306
- if (config == null) throw new ArgumentNullException(nameof(config));
307
- if (record == null) throw new ArgumentNullException(nameof(record));
308
- ApplyValues(config, record.OverrideValues);
309
- }
310
-
311
- static void ApplyValues(UnityCopilotPlugin.UnityConnectionConfig config, IReadOnlyDictionary<string, object?> values)
312
- {
313
- foreach (var kvp in values)
314
- {
315
- switch (kvp.Key)
316
- {
317
- case FieldHost:
318
- config.LocalHost = (string?)kvp.Value ?? UnityCopilotPlugin.UnityConnectionConfig.DefaultHost;
319
- break;
320
- case FieldKeepConnected:
321
- if (kvp.Value is bool kc) config.KeepConnected = kc;
322
- break;
323
- case FieldAuthOption:
324
- if (kvp.Value is AuthOption ao) config.AuthOption = ao;
325
- break;
326
- case FieldLocalToken:
327
- config.LocalToken = (string?)kvp.Value;
328
- break;
329
- case FieldTools:
330
- config.EnabledToolsOverride = (List<string>?)kvp.Value;
331
- break;
332
- case FieldStartServer:
333
- if (kvp.Value is bool ss) config.KeepServerRunning = ss;
334
- break;
335
- case FieldTransport:
336
- if (kvp.Value is TransportMethod tm) config.TransportMethod = tm;
337
- break;
338
- case FieldConnectionMode:
339
- if (kvp.Value is ConnectionMode cm) config.ConnectionMode = cm;
340
- break;
341
- default:
342
- // Fail loudly if a new Field* constant is added to Track but forgotten here —
343
- // a silent miss would let runtime overrides leak to disk on Save.
344
- throw new InvalidOperationException($"Unhandled override field: {kvp.Key}");
345
- }
346
- }
347
- }
348
-
349
- /// <summary>
350
- /// Returns true if the given URL targets a loopback host
351
- /// (<c>localhost</c>, <c>127.0.0.0/8</c>, or IPv6 <c>::1</c>).
352
- /// Used to infer <see cref="ConnectionMode.Custom"/> when a worktree-style local URL is supplied.
353
- /// </summary>
354
- public static bool IsLoopbackUrl(string url)
355
- {
356
- if (string.IsNullOrWhiteSpace(url))
357
- return false;
358
- if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
359
- return false;
360
- var host = uri.Host;
361
- if (string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase))
362
- return true;
363
- if (System.Net.IPAddress.TryParse(host, out var ip))
364
- return System.Net.IPAddress.IsLoopback(ip);
365
- return false;
366
- }
367
- }
368
- }
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.Collections.Generic;
14
+ using com.AtelierAI.Uco.Framework.Common.Utils;
15
+ using com.AtelierAI.Unity.Copilot.Utils;
16
+ using Microsoft.Extensions.Logging;
17
+ using static com.AtelierAI.Uco.Framework.Common.Consts.Uco.Server;
18
+
19
+ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
20
+ {
21
+ /// <summary>
22
+ /// Loads Uco plugin configuration from layered sources and (optionally) applies
23
+ /// runtime overrides from environment variables and process command-line arguments.
24
+ ///
25
+ /// Priority (highest wins):
26
+ /// 1. Process command-line flags (e.g. <c>--url</c>, <c>--token</c>, <c>--auth</c>,
27
+ /// or any <c>--UNITY_COPILOT_*</c> variant)
28
+ /// 2. Process environment variables (<c>UNITY_COPILOT_*</c>)
29
+ /// 3. On-disk config (<c>UserSettings/AI-Game-Developer-Config.json</c>)
30
+ /// 4. Built-in defaults
31
+ ///
32
+ /// Overrides applied via env vars / flags are NEVER persisted back to disk —
33
+ /// they are runtime-only. The <see cref="OverrideRecord"/> returned by
34
+ /// <see cref="ApplyEnvironmentOverrides"/> captures both the disk-baseline values
35
+ /// and the override values so that the editor's Save() flow can restore the
36
+ /// baseline before serializing. See <c>UnityCopilotPluginEditor.Save</c>.
37
+ /// </summary>
38
+ public static class EnvironmentUtils
39
+ {
40
+ static readonly ILogger _logger = UnityLoggerFactory.LoggerFactory.CreateLogger(nameof(EnvironmentUtils));
41
+
42
+ // Environment variable names for Uco connection overrides.
43
+ public const string EnvHost = "UNITY_COPILOT_HOST";
44
+ public const string EnvKeepConnected = "UNITY_COPILOT_KEEP_CONNECTED";
45
+ public const string EnvAuthOption = "UNITY_COPILOT_AUTH_OPTION";
46
+ public const string EnvToken = "UNITY_COPILOT_TOKEN";
47
+ public const string EnvTools = "UNITY_COPILOT_TOOLS";
48
+ public const string EnvStartServer = "UNITY_COPILOT_START_SERVER";
49
+ public const string EnvTransport = "UNITY_COPILOT_TRANSPORT";
50
+ public const string EnvConnectionMode = "UNITY_COPILOT_CONNECTION_MODE";
51
+
52
+ // Short flag aliases recognised by the in-plugin command-line parser.
53
+ // The CLI tool already translates these to the equivalent env vars before
54
+ // launching Unity, but the plugin still parses them directly so
55
+ // out-of-band invocations (manual editor launch, IDE config, etc.) work.
56
+ public const string FlagUrl = "url";
57
+ public const string FlagToken = "token";
58
+ public const string FlagAuth = "auth";
59
+
60
+ // Field-name keys used by OverrideRecord to track which fields were overridden
61
+ // by env/flags so the Save flow can restore disk-baseline values before writing.
62
+ public const string FieldHost = nameof(UnityCopilotPlugin.UnityConnectionConfig.LocalHost);
63
+ public const string FieldKeepConnected = nameof(UnityCopilotPlugin.UnityConnectionConfig.KeepConnected);
64
+ public const string FieldAuthOption = nameof(UnityCopilotPlugin.UnityConnectionConfig.AuthOption);
65
+ public const string FieldLocalToken = nameof(UnityCopilotPlugin.UnityConnectionConfig.LocalToken);
66
+ public const string FieldTools = nameof(UnityCopilotPlugin.UnityConnectionConfig.EnabledToolsOverride);
67
+ public const string FieldStartServer = nameof(UnityCopilotPlugin.UnityConnectionConfig.KeepServerRunning);
68
+ public const string FieldTransport = nameof(UnityCopilotPlugin.UnityConnectionConfig.TransportMethod);
69
+ public const string FieldConnectionMode = nameof(UnityCopilotPlugin.UnityConnectionConfig.ConnectionMode);
70
+
71
+ /// <summary>
72
+ /// Captures, per overridden field, the disk-baseline value (what was read from JSON)
73
+ /// and the runtime override value applied on top. Allows <c>Save()</c> to round-trip
74
+ /// the baseline to disk while keeping the runtime override on the in-memory config.
75
+ /// Empty when no env/flag overrides were detected.
76
+ /// </summary>
77
+ public sealed class OverrideRecord
78
+ {
79
+ readonly Dictionary<string, object?> _baselineValues = new();
80
+ readonly Dictionary<string, object?> _overrideValues = new();
81
+
82
+ public IReadOnlyDictionary<string, object?> BaselineValues => _baselineValues;
83
+ public IReadOnlyDictionary<string, object?> OverrideValues => _overrideValues;
84
+
85
+ public bool HasAny => _baselineValues.Count > 0;
86
+ public bool Contains(string fieldName) => _baselineValues.ContainsKey(fieldName);
87
+
88
+ internal void Track(string fieldName, object? baselineValue, object? overrideValue)
89
+ {
90
+ _baselineValues[fieldName] = baselineValue;
91
+ _overrideValues[fieldName] = overrideValue;
92
+ }
93
+ }
94
+
95
+ /// <summary>
96
+ /// Checks if the current environment is a CI environment.
97
+ /// </summary>
98
+ public static bool IsCi()
99
+ {
100
+ var commandLineArgs = ArgsUtils.ParseCommandLineArguments();
101
+
102
+ var ci = commandLineArgs.GetValueOrDefault("CI") ?? Environment.GetEnvironmentVariable("CI");
103
+ var gha = commandLineArgs.GetValueOrDefault("GITHUB_ACTIONS") ?? Environment.GetEnvironmentVariable("GITHUB_ACTIONS");
104
+ var az = commandLineArgs.GetValueOrDefault("TF_BUILD") ?? Environment.GetEnvironmentVariable("TF_BUILD"); // Azure Pipelines
105
+
106
+ return string.Equals(ci?.Trim()?.Trim('"'), "true", StringComparison.OrdinalIgnoreCase)
107
+ || string.Equals(gha?.Trim()?.Trim('"'), "true", StringComparison.OrdinalIgnoreCase)
108
+ || string.Equals(az?.Trim()?.Trim('"'), "true", StringComparison.OrdinalIgnoreCase);
109
+ }
110
+
111
+ /// <summary>
112
+ /// Checks if the Editor was launched with -batchmode (COCli-13).
113
+ /// Batchmode launches without a configured server (offline builds,
114
+ /// command-line automation) must not run the connection retry loop —
115
+ /// its warnings would pollute BuildReport output.
116
+ /// </summary>
117
+ public static bool IsBatchMode()
118
+ => IsBatchMode(UnityEngine.Application.isBatchMode, ArgsUtils.ParseCommandLineArguments());
119
+
120
+ /// <summary>Test-friendly overload taking the parsed command-line args.</summary>
121
+ public static bool IsBatchMode(
122
+ bool applicationIsBatchMode,
123
+ IReadOnlyDictionary<string, string> commandLineArgs)
124
+ => applicationIsBatchMode || commandLineArgs.ContainsKey("batchmode");
125
+
126
+ /// <summary>
127
+ /// Applies environment-variable and command-line-argument overrides to the given config.
128
+ /// Args (highest priority) override env vars, env vars override the disk-baseline values
129
+ /// already present on <paramref name="config"/>. Returns an <see cref="OverrideRecord"/>
130
+ /// that captures the disk-baseline value for each field that was overridden.
131
+ /// </summary>
132
+ public static OverrideRecord ApplyEnvironmentOverrides(UnityCopilotPlugin.UnityConnectionConfig config)
133
+ {
134
+ var args = ArgsUtils.ParseCommandLineArguments();
135
+ return ApplyEnvironmentOverrides(config, args, Environment.GetEnvironmentVariable);
136
+ }
137
+
138
+ /// <summary>
139
+ /// Test-friendly overload. <paramref name="argReader"/> is the parsed command-line
140
+ /// arg dictionary (keys without leading dashes); <paramref name="envReader"/> resolves
141
+ /// environment variables. Either may be empty / always-null to disable that source.
142
+ /// </summary>
143
+ public static OverrideRecord ApplyEnvironmentOverrides(
144
+ UnityCopilotPlugin.UnityConnectionConfig config,
145
+ IReadOnlyDictionary<string, string> argReader,
146
+ Func<string, string?> envReader)
147
+ {
148
+ if (config == null) throw new ArgumentNullException(nameof(config));
149
+ if (argReader == null) throw new ArgumentNullException(nameof(argReader));
150
+ if (envReader == null) throw new ArgumentNullException(nameof(envReader));
151
+
152
+ var record = new OverrideRecord();
153
+
154
+ // Resolve a value with priority: short-flag-alias (highest) > UNITY_COPILOT_* env-style flag > env var.
155
+ // Returns null if no source provided a non-empty value.
156
+ string? Resolve(string envKey, string? flagAlias)
157
+ {
158
+ if (!string.IsNullOrEmpty(flagAlias)
159
+ && argReader.TryGetValue(flagAlias, out var flagValue)
160
+ && !string.IsNullOrWhiteSpace(flagValue))
161
+ {
162
+ return flagValue;
163
+ }
164
+ if (argReader.TryGetValue(envKey, out var envFlagValue)
165
+ && !string.IsNullOrWhiteSpace(envFlagValue))
166
+ {
167
+ return envFlagValue;
168
+ }
169
+ var envValue = envReader(envKey);
170
+ if (!string.IsNullOrWhiteSpace(envValue))
171
+ return envValue;
172
+ return null;
173
+ }
174
+
175
+ string Sanitize(string raw) => raw.Trim().Trim('"');
176
+
177
+ // UNITY_COPILOT_HOST / --url override the local server host.
178
+ string? sanitizedHost = null;
179
+ var rawHost = Resolve(EnvHost, FlagUrl);
180
+ if (rawHost != null)
181
+ {
182
+ var host = Sanitize(rawHost).TrimEnd('/');
183
+ if (host.Length > 0)
184
+ {
185
+ sanitizedHost = host;
186
+ if (!string.Equals(host, config.LocalHost, StringComparison.Ordinal))
187
+ {
188
+ record.Track(FieldHost, config.LocalHost, host);
189
+ config.LocalHost = host;
190
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", FieldHost, host);
191
+ }
192
+ }
193
+ }
194
+
195
+ // Loopback URLs without an explicit mode infer Custom (worktree / local-dev).
196
+ // Remote URLs without an explicit mode leave the disk-baseline ConnectionMode untouched.
197
+ var rawMode = Resolve(EnvConnectionMode, flagAlias: null);
198
+ ConnectionMode? targetMode = null;
199
+ if (rawMode != null && Enum.TryParse<ConnectionMode>(Sanitize(rawMode), ignoreCase: true, out var explicitMode))
200
+ {
201
+ targetMode = explicitMode;
202
+ }
203
+ else if (sanitizedHost != null && IsLoopbackUrl(sanitizedHost))
204
+ {
205
+ targetMode = ConnectionMode.Custom;
206
+ }
207
+ if (targetMode.HasValue && targetMode.Value != config.ConnectionMode)
208
+ {
209
+ record.Track(FieldConnectionMode, config.ConnectionMode, targetMode.Value);
210
+ config.ConnectionMode = targetMode.Value;
211
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", FieldConnectionMode, targetMode.Value);
212
+ }
213
+
214
+ var rawKeep = Resolve(EnvKeepConnected, flagAlias: null);
215
+ if (rawKeep != null && bool.TryParse(Sanitize(rawKeep), out var keep) && keep != config.KeepConnected)
216
+ {
217
+ record.Track(FieldKeepConnected, config.KeepConnected, keep);
218
+ config.KeepConnected = keep;
219
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", EnvKeepConnected, keep);
220
+ }
221
+
222
+ var rawAuth = Resolve(EnvAuthOption, FlagAuth);
223
+ if (rawAuth != null
224
+ && Enum.TryParse<AuthOption>(Sanitize(rawAuth), ignoreCase: true, out var ao)
225
+ && ao != config.AuthOption)
226
+ {
227
+ record.Track(FieldAuthOption, config.AuthOption, ao);
228
+ config.AuthOption = ao;
229
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", EnvAuthOption, ao);
230
+ }
231
+
232
+ // We track the specific
233
+ // backing field rather than the abstract Token property because only the backing
234
+ // fields are serialised — restoring the baseline must target the same field that
235
+ // was clobbered.
236
+ var rawToken = Resolve(EnvToken, FlagToken);
237
+ if (rawToken != null)
238
+ {
239
+ var token = Sanitize(rawToken);
240
+ if (!string.Equals(token, config.LocalToken, StringComparison.Ordinal))
241
+ {
242
+ record.Track(FieldLocalToken, config.LocalToken, token);
243
+ config.LocalToken = token;
244
+ _logger.LogInformation("[Uco] Override: {Key}=*** (LocalToken)", EnvToken);
245
+ }
246
+ }
247
+
248
+ var rawTransport = Resolve(EnvTransport, flagAlias: null);
249
+ if (rawTransport != null
250
+ && Enum.TryParse<TransportMethod>(Sanitize(rawTransport), ignoreCase: true, out var tm)
251
+ && tm != config.TransportMethod)
252
+ {
253
+ record.Track(FieldTransport, config.TransportMethod, tm);
254
+ config.TransportMethod = tm;
255
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", EnvTransport, tm);
256
+ }
257
+
258
+ var rawStart = Resolve(EnvStartServer, flagAlias: null);
259
+ if (rawStart != null && bool.TryParse(Sanitize(rawStart), out var ss) && ss != config.KeepServerRunning)
260
+ {
261
+ record.Track(FieldStartServer, config.KeepServerRunning, ss);
262
+ config.KeepServerRunning = ss;
263
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", EnvStartServer, ss);
264
+ }
265
+
266
+ // EnabledToolsOverride is [JsonIgnore] so it is never persisted regardless of the
267
+ // baseline-restoration logic; we still track it for completeness.
268
+ var rawTools = Resolve(EnvTools, flagAlias: null);
269
+ if (rawTools != null)
270
+ {
271
+ var ids = rawTools.Split(',', StringSplitOptions.RemoveEmptyEntries);
272
+ var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
273
+ var trimmed = new List<string>(ids.Length);
274
+ foreach (var id in ids)
275
+ {
276
+ var value = Sanitize(id);
277
+ if (!string.IsNullOrWhiteSpace(value) && seen.Add(value))
278
+ trimmed.Add(value);
279
+ }
280
+ record.Track(FieldTools, config.EnabledToolsOverride, trimmed);
281
+ config.EnabledToolsOverride = trimmed;
282
+ _logger.LogInformation("[Uco] Override: {Key}={Value}", EnvTools, rawTools.Trim());
283
+ }
284
+
285
+ return record;
286
+ }
287
+
288
+ /// <summary>
289
+ /// Applies the BaselineValues from <paramref name="record"/> to <paramref name="config"/>
290
+ /// (i.e. reverses runtime overrides so the in-memory config reflects what is on disk).
291
+ /// Used by the editor's Save() flow to ensure runtime-only overrides are not persisted.
292
+ /// </summary>
293
+ public static void ApplyBaseline(UnityCopilotPlugin.UnityConnectionConfig config, OverrideRecord record)
294
+ {
295
+ if (config == null) throw new ArgumentNullException(nameof(config));
296
+ if (record == null) throw new ArgumentNullException(nameof(record));
297
+ ApplyValues(config, record.BaselineValues);
298
+ }
299
+
300
+ /// <summary>
301
+ /// Re-applies the OverrideValues from <paramref name="record"/> to <paramref name="config"/>
302
+ /// (i.e. restores runtime overrides after a temporary baseline-restore).
303
+ /// </summary>
304
+ public static void ApplyOverrides(UnityCopilotPlugin.UnityConnectionConfig config, OverrideRecord record)
305
+ {
306
+ if (config == null) throw new ArgumentNullException(nameof(config));
307
+ if (record == null) throw new ArgumentNullException(nameof(record));
308
+ ApplyValues(config, record.OverrideValues);
309
+ }
310
+
311
+ static void ApplyValues(UnityCopilotPlugin.UnityConnectionConfig config, IReadOnlyDictionary<string, object?> values)
312
+ {
313
+ foreach (var kvp in values)
314
+ {
315
+ switch (kvp.Key)
316
+ {
317
+ case FieldHost:
318
+ config.LocalHost = (string?)kvp.Value ?? UnityCopilotPlugin.UnityConnectionConfig.DefaultHost;
319
+ break;
320
+ case FieldKeepConnected:
321
+ if (kvp.Value is bool kc) config.KeepConnected = kc;
322
+ break;
323
+ case FieldAuthOption:
324
+ if (kvp.Value is AuthOption ao) config.AuthOption = ao;
325
+ break;
326
+ case FieldLocalToken:
327
+ config.LocalToken = (string?)kvp.Value;
328
+ break;
329
+ case FieldTools:
330
+ config.EnabledToolsOverride = (List<string>?)kvp.Value;
331
+ break;
332
+ case FieldStartServer:
333
+ if (kvp.Value is bool ss) config.KeepServerRunning = ss;
334
+ break;
335
+ case FieldTransport:
336
+ if (kvp.Value is TransportMethod tm) config.TransportMethod = tm;
337
+ break;
338
+ case FieldConnectionMode:
339
+ if (kvp.Value is ConnectionMode cm) config.ConnectionMode = cm;
340
+ break;
341
+ default:
342
+ // Fail loudly if a new Field* constant is added to Track but forgotten here —
343
+ // a silent miss would let runtime overrides leak to disk on Save.
344
+ throw new InvalidOperationException($"Unhandled override field: {kvp.Key}");
345
+ }
346
+ }
347
+ }
348
+
349
+ /// <summary>
350
+ /// Returns true if the given URL targets a loopback host
351
+ /// (<c>localhost</c>, <c>127.0.0.0/8</c>, or IPv6 <c>::1</c>).
352
+ /// Used to infer <see cref="ConnectionMode.Custom"/> when a worktree-style local URL is supplied.
353
+ /// </summary>
354
+ public static bool IsLoopbackUrl(string url)
355
+ {
356
+ if (string.IsNullOrWhiteSpace(url))
357
+ return false;
358
+ if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
359
+ return false;
360
+ var host = uri.Host;
361
+ if (string.Equals(host, "localhost", StringComparison.OrdinalIgnoreCase))
362
+ return true;
363
+ if (System.Net.IPAddress.TryParse(host, out var ip))
364
+ return System.Net.IPAddress.IsLoopback(ip);
365
+ return false;
366
+ }
367
+ }
368
+ }