@atelierai/uco 1.0.1 → 1.0.3

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 (57) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/README.md +3 -3
  3. package/dist/codegen/emit.js +1 -1
  4. package/dist/codegen/fetch.js +1 -1
  5. package/dist/codegen/fetch.js.map +1 -1
  6. package/dist/commands/devops/login.js +1 -1
  7. package/dist/commands/devops/login.js.map +1 -1
  8. package/dist/commands/devops/setup-mcp.js +1 -1
  9. package/dist/commands/devops/setup-mcp.js.map +1 -1
  10. package/dist/commands/gen.js +2 -2
  11. package/dist/commands/gen.js.map +1 -1
  12. package/dist/commands/init.js +31 -10
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/ping.js +2 -2
  15. package/dist/commands/ping.js.map +1 -1
  16. package/dist/config/resolve.js +1 -1
  17. package/dist/config/resolve.js.map +1 -1
  18. package/dist/devops/utils/agents.js +1 -1
  19. package/dist/devops/utils/agents.js.map +1 -1
  20. package/dist/generated/tools.js +1 -1
  21. package/dist/generated/tools.js.map +1 -1
  22. package/docs/INSTALL.zh-CN.md +1 -1
  23. package/package.json +13 -4
  24. package/skills/uco-setup/SKILL.md +2 -2
  25. package/skills/uco-setup/references/recovery.md +26 -2
  26. package/skills/unity-editor/SKILL.md +1 -1
  27. package/vendor/plugin/com.atelierai.unity.copilot/CHANGELOG.md +48 -15
  28. package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetResolverMenu.cs +3 -1
  29. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Branding/ProductInfo.cs +4 -5
  30. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +32 -42
  31. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Skills/Skill_InitialSetup.cs +1 -1
  32. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/MenuItems.cs +7 -66
  33. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Overlay/OpenWindowButton.cs +2 -2
  34. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/UnityCopilotProjectSettingsProvider.cs +5 -5
  35. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.Connection.cs +177 -409
  36. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CreateGUI.cs +3 -10
  37. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.cs +2 -71
  38. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/UpdatePopupWindow.cs +2 -2
  39. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Config.cs +6 -1
  40. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Static.cs +9 -12
  41. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.cs +1 -1
  42. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolsManifestGenerator.cs +1 -1
  43. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityCopilotUpdateProjectSettings.cs +2 -2
  44. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UpdateChecker.cs +3 -3
  45. package/vendor/plugin/com.atelierai.unity.copilot/README.md +2 -2
  46. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Config.cs +11 -62
  47. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.cs +1 -1
  48. package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Utils/EnvironmentUtils.cs +7 -25
  49. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +260 -320
  50. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Tool/ToolSetEnabledStateTests.cs +1 -1
  51. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/UI/MainWindowEditor.StatusLogicTests.cs +0 -125
  52. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/UI/SceneViewToolbarOverlayTests.cs +1 -1
  53. package/vendor/plugin/com.atelierai.unity.copilot/package.json +3 -3
  54. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Services/DeviceAuthFlow.cs +0 -133
  55. package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Services/DeviceAuthFlow.cs.meta +0 -11
  56. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/CopilotServerManagerAutoStartTests.cs +0 -43
  57. package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/CopilotServerManagerAutoStartTests.cs.meta +0 -11
@@ -23,19 +23,15 @@ namespace com.AtelierAI.Unity.Copilot.Editor.UI
23
23
  readonly CompositeDisposable _disposables = new();
24
24
 
25
25
  Button? _btnConnect;
26
- Button? _btnAuthorize;
27
- Action? _startAuthorizeAction;
28
26
  VisualElement? _timelinePointUnity;
29
- AlertPanel? _connectionAuthAlert;
30
- AlertPanel? _connectionConnectAlert;
31
27
 
32
- protected override string WindowTitle => "Unity Co-Pilot";
28
+ protected override string WindowTitle => "Unity Copilot";
33
29
  protected override string[] WindowUxmlPaths => _windowUxmlPaths;
34
30
  protected override string[] WindowUssPaths => _windowUssPaths;
35
31
 
36
32
  public static MainWindowEditor ShowWindow()
37
33
  {
38
- var window = GetWindow<MainWindowEditor>("Unity Co-Pilot");
34
+ var window = GetWindow<MainWindowEditor>("Unity Copilot");
39
35
  window.SetupWindowWithIcon();
40
36
  window.Focus();
41
37
 
@@ -73,76 +69,11 @@ namespace com.AtelierAI.Unity.Copilot.Editor.UI
73
69
  _authRejectedSubscription.Dispose();
74
70
  }
75
71
 
76
- internal static (bool needsAuth, bool hasToken, bool isCloud) ComputeCloudAuthState(ConnectionMode mode, string? token)
77
- {
78
- var isCloud = mode == ConnectionMode.Cloud;
79
- var hasToken = !string.IsNullOrEmpty(token);
80
- var needsAuth = isCloud && !hasToken;
81
- return (needsAuth, hasToken, isCloud);
82
- }
83
-
84
- private void UpdateCloudAuthState()
85
- {
86
- var (needsAuth, hasToken, isCloud) = ComputeCloudAuthState(UnityCopilotPluginEditor.ConnectionMode, UnityCopilotPluginEditor.CloudToken);
87
-
88
- if (_timelinePointUnity != null)
89
- {
90
- _timelinePointUnity.SetEnabled(!needsAuth);
91
- _timelinePointUnity.tooltip = needsAuth
92
- ? "Cloud token is required. Press the Authorize button to authenticate."
93
- : "";
94
- }
95
- if (_btnConnect != null)
96
- {
97
- if (needsAuth)
98
- {
99
- _btnConnect.text = ServerButtonText_Connect;
100
- _btnConnect.EnableInClassList("btn-primary", false);
101
- _btnConnect.EnableInClassList("btn-secondary", true);
102
- }
103
- else if (isCloud && hasToken
104
- && _btnConnect.text == ServerButtonText_Connect)
105
- {
106
- _btnConnect.EnableInClassList("btn-primary", true);
107
- _btnConnect.EnableInClassList("btn-secondary", false);
108
- }
109
- }
110
- if (_btnAuthorize != null)
111
- {
112
- _btnAuthorize.EnableInClassList("btn-primary", !hasToken);
113
- }
114
- _connectionAuthAlert?.SetVisible(needsAuth);
115
-
116
- // Show connect alert when authorized in Cloud mode but not connected and not trying
117
- if (_connectionConnectAlert != null)
118
- {
119
- var connectionState = UnityCopilotPluginEditor.ConnectionState.CurrentValue;
120
- var keepConnected = UnityCopilotPluginEditor.KeepConnected;
121
- var isDisconnected = connectionState == ConnectionState.Disconnected;
122
- var needsConnect = isCloud && hasToken && isDisconnected && !keepConnected;
123
- _connectionConnectAlert.SetVisible(needsConnect);
124
- }
125
- }
126
-
127
72
  private static void UnityBuildAndConnect()
128
73
  {
129
74
  UnityCopilotPluginEditor.Instance.BuildMcpPluginIfNeeded();
130
75
  UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
131
76
  UnityCopilotPluginEditor.ConnectIfNeeded();
132
77
  }
133
-
134
- /// <summary>
135
- /// Disconnects, disposes the current MCP plugin, rebuilds it (picking up the new Host/Token
136
- /// from the changed ConnectionMode), and reconnects if KeepConnected is enabled.
137
- /// Called when switching between Local and Cloud modes.
138
- /// </summary>
139
- private static void ReconnectAfterModeSwitch()
140
- {
141
- if (UnityCopilotPluginEditor.Instance.HasMcpPluginInstance)
142
- {
143
- UnityCopilotPluginEditor.Instance.DisposeMcpPluginInstance();
144
- }
145
- UnityBuildAndConnect();
146
- }
147
78
  }
148
79
  }
@@ -23,7 +23,7 @@ using UnityEngine.UIElements;
23
23
  namespace com.AtelierAI.Unity.Copilot.Editor.UI
24
24
  {
25
25
  /// <summary>
26
- /// A popup window that notifies the user when a new version of Unity Co-Pilot is available.
26
+ /// A popup window that notifies the user when a new version of Unity Copilot is available.
27
27
  /// </summary>
28
28
  public class UpdatePopupWindow : NotificationPopupWindow
29
29
  {
@@ -197,7 +197,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.UI
197
197
  UnityCopilotPluginEditor.Instance.LogInfo("Package updated to version {version}", typeof(UpdatePopupWindow), latestVersion);
198
198
  EditorUtility.DisplayDialog(
199
199
  "Update Complete",
200
- $"Unity Co-Pilot has been updated to version {latestVersion}.\n\nUnity will recompile scripts automatically.",
200
+ $"Unity Copilot has been updated to version {latestVersion}.\n\nUnity will recompile scripts automatically.",
201
201
  "OK");
202
202
  }
203
203
  else if (addRequest.Status >= StatusCode.Failure)
@@ -138,7 +138,12 @@ namespace com.AtelierAI.Unity.Copilot
138
138
  {
139
139
  config = string.IsNullOrWhiteSpace(json)
140
140
  ? null
141
- : JsonSerializer.Deserialize<UnityConnectionConfig>(json!, new JsonSerializerOptions
141
+ : JsonSerializer.Deserialize<UnityConnectionConfig>(
142
+ // Legacy 1.0.2-and-earlier configs may carry the removed Cloud
143
+ // connection mode; JsonStringEnumConverter would throw on it.
144
+ json!.Replace("\"connectionMode\": \"Cloud\"", "\"connectionMode\": \"Custom\"")
145
+ .Replace("\"ConnectionMode\": \"Cloud\"", "\"ConnectionMode\": \"Custom\""),
146
+ new JsonSerializerOptions
142
147
  {
143
148
  PropertyNameCaseInsensitive = true,
144
149
  Converters = { new JsonStringEnumConverter() }
@@ -101,6 +101,15 @@ namespace com.AtelierAI.Unity.Copilot
101
101
  NotifyChanged(Instance.unityConnectionConfig);
102
102
  }
103
103
  }
104
+ public static string? LocalToken
105
+ {
106
+ get => Instance.unityConnectionConfig.LocalToken;
107
+ set
108
+ {
109
+ Instance.unityConnectionConfig.LocalToken = value;
110
+ NotifyChanged(Instance.unityConnectionConfig);
111
+ }
112
+ }
104
113
  public static string LocalHost
105
114
  {
106
115
  get => Instance.unityConnectionConfig.LocalHost;
@@ -229,18 +238,6 @@ namespace com.AtelierAI.Unity.Copilot
229
238
  NotifyChanged(Instance.unityConnectionConfig);
230
239
  }
231
240
  }
232
- public static string CloudServerUrl => UnityCopilotPlugin.UnityConnectionConfig.CloudServerUrl;
233
- public static string? CloudToken
234
- {
235
- get => Instance.unityConnectionConfig.CloudToken;
236
- set
237
- {
238
- Instance.unityConnectionConfig.CloudToken = value;
239
- NotifyChanged(Instance.unityConnectionConfig);
240
- }
241
- }
242
-
243
-
244
241
 
245
242
  // 'new' is intentional: static dispatch on the subtype, instance logic lives in the base.
246
243
  public static new ReadOnlyReactiveProperty<WsState> ConnectionState
@@ -15,7 +15,7 @@ namespace com.AtelierAI.Unity.Copilot
15
15
  {
16
16
  /// <summary>
17
17
  /// Editor-only singleton that owns the persistent MCP connection used
18
- /// by Unity Editor tooling (AI Game Developer window, configurators, etc.).
18
+ /// by Unity Editor tooling (Copilot window, configurators, etc.).
19
19
  /// Lives in the Editor assembly — not accessible from Runtime code.
20
20
  /// </summary>
21
21
  public partial class UnityCopilotPluginEditor : UnityCopilotPlugin
@@ -40,7 +40,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.Utils
40
40
  /// so the shipped manifest is deterministic across projects.
41
41
  /// </para>
42
42
  /// <para>
43
- /// Menu: <b>Tools / AI Game Developer / Generate Tools Manifest</b>.
43
+ /// Menu: <b>Tools / Unity Copilot / Generate Tools Manifest</b>.
44
44
  /// Requires an embedded or local-copy package installation (writes into
45
45
  /// <c>Packages/com.atelierai.unity.copilot/</c>).
46
46
  /// </para>
@@ -16,7 +16,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.Utils
16
16
  {
17
17
  /// <summary>
18
18
  /// Team-shared settings for the Unity-MCP update checker, persisted under
19
- /// <c>ProjectSettings/AI-Game-Developer-UpdateSettings.asset</c>.
19
+ /// <c>ProjectSettings/Copilot-UpdateSettings.asset</c>.
20
20
  /// </summary>
21
21
  /// <remarks>
22
22
  /// Uses Unity's <see cref="ScriptableSingleton{T}"/> + <see cref="FilePathAttribute"/> pattern
@@ -38,7 +38,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.Utils
38
38
  /// <c>ProjectSettings/</c>) — NOT against <c>Assets/</c>. That places the asset alongside
39
39
  /// other team-shared editor settings such as <c>ProjectSettings/EditorSettings.asset</c>.
40
40
  /// </remarks>
41
- [FilePath("ProjectSettings/AI-Game-Developer-UpdateSettings.asset", FilePathAttribute.Location.ProjectFolder)]
41
+ [FilePath("ProjectSettings/Copilot-UpdateSettings.asset", FilePathAttribute.Location.ProjectFolder)]
42
42
  internal sealed class UnityCopilotUpdateProjectSettings : ScriptableSingleton<UnityCopilotUpdateProjectSettings>
43
43
  {
44
44
  [SerializeField] private bool disableUpdateNotificationsForTeam;
@@ -33,7 +33,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.Utils
33
33
  ///
34
34
  /// Two opt-out layers gate the popup, in this order:
35
35
  /// 1. <see cref="IsDisabledForProject"/> — team-shared, stored in
36
- /// <c>ProjectSettings/AI-Game-Developer-UpdateSettings.asset</c> via
36
+ /// <c>ProjectSettings/Copilot-UpdateSettings.asset</c> via
37
37
  /// <see cref="UnityCopilotUpdateProjectSettings"/>. Set this once and commit it to
38
38
  /// disable the popup for every team member who clones the project. See
39
39
  /// https://github.com/IvanMurzak/uco-plugin/issues/768.
@@ -112,7 +112,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.Utils
112
112
  /// <summary>
113
113
  /// Gets whether the team-wide kill-switch is enabled for this project. When <c>true</c>,
114
114
  /// the popup is suppressed for every team member who has the
115
- /// <c>ProjectSettings/AI-Game-Developer-UpdateSettings.asset</c> file in their checkout,
115
+ /// <c>ProjectSettings/Copilot-UpdateSettings.asset</c> file in their checkout,
116
116
  /// regardless of their per-user <see cref="IsDoNotShowAgain"/> state.
117
117
  /// </summary>
118
118
  /// <remarks>
@@ -223,7 +223,7 @@ namespace com.AtelierAI.Unity.Copilot.Editor.Utils
223
223
  /// team-shared via <c>ProjectSettings/</c>, and clearing it from a debug menu would
224
224
  /// produce a spurious diff in a committed asset (potentially surprising other team
225
225
  /// members). The team flag is reset only through the Project Settings UI or
226
- /// <c>Tools ▸ AI Game Developer ▸ Updates ▸ Disable Update Notifications (Team)</c>.
226
+ /// <c>Tools ▸ Unity Copilot ▸ Updates ▸ Disable Update Notifications (Team)</c>.
227
227
  /// </remarks>
228
228
  public static void ClearPreferences()
229
229
  {
@@ -1,10 +1,10 @@
1
1
  <div align="center">
2
- <h1>Unity Co-Pilot</h1>
2
+ <h1>Unity Copilot</h1>
3
3
  <p>Drive the Unity Editor from any AI agent over plain REST + WebSocket — no MCP protocol on the wire.</p>
4
4
  <p><code>com.atelierai.unity.copilot</code></p>
5
5
  </div>
6
6
 
7
- Unity Co-Pilot is a Unity Editor/Runtime plugin that exposes the Editor as an
7
+ Unity Copilot is a Unity Editor/Runtime plugin that exposes the Editor as an
8
8
  HTTP service: 160+ tools covering scenes, GameObjects, components, assets,
9
9
  prefabs, scripts, packages, screenshots, console, tests, and builds — plus
10
10
  prompts and resources. A self-hosted Node bridge connects the Editor to the
@@ -35,87 +35,36 @@ namespace com.AtelierAI.Unity.Copilot
35
35
  public static List<CopilotFeature> DefaultResources => new();
36
36
 
37
37
  /// <summary>
38
- /// Backing field for the local server URL. Serialized as "host" in JSON.
39
- /// Use <see cref="Host"/> for the active connection URL (routes through Cloud mode).
38
+ /// The local server URL. Serialized as "host" in JSON.
40
39
  /// </summary>
41
40
  [JsonPropertyName("host")]
42
41
  public string LocalHost { get; set; } = DefaultHost;
43
42
 
44
43
  /// <summary>
45
- /// Backing field for the local auth token. Serialized as "token" in JSON.
46
- /// Use <see cref="Token"/> for the active token (routes through Cloud mode).
44
+ /// The local auth token. Serialized as "token" in JSON.
47
45
  /// </summary>
48
46
  [JsonPropertyName("token")]
49
47
  public string? LocalToken { get; set; }
50
48
 
51
- public const string DefaultCloudServerBaseUrl = "https://ai-game.dev";
52
-
53
- public static string CloudServerBaseUrl
54
- {
55
- get
56
- {
57
- var args = ArgsUtils.ParseCommandLineArguments();
58
- var envValue = args.GetValueOrDefault(EnvironmentUtils.EnvCloudUrl)
59
- ?? Environment.GetEnvironmentVariable(EnvironmentUtils.EnvCloudUrl);
60
-
61
- if (string.IsNullOrWhiteSpace(envValue))
62
- return DefaultCloudServerBaseUrl;
63
-
64
- var normalized = envValue.Trim().Trim('"').TrimEnd('/');
65
-
66
- if (!Uri.TryCreate(normalized, UriKind.Absolute, out var uri) ||
67
- (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps))
68
- {
69
- return DefaultCloudServerBaseUrl;
70
- }
71
-
72
- // Strip trailing "/mcp" so CloudServerUrl doesn't produce "/mcp/mcp"
73
- if (normalized.EndsWith("/mcp", StringComparison.OrdinalIgnoreCase))
74
- normalized = normalized[..^4];
75
-
76
- return normalized;
77
- }
78
- }
79
-
80
- public static string CloudServerUrl => CloudServerBaseUrl + "/mcp";
81
-
82
- /// <summary>
83
- /// Returns the active connection host based on <see cref="ConnectionMode"/>.
84
- /// In Cloud mode, returns <see cref="CloudServerUrl"/>.
85
- /// In Local mode, returns <see cref="LocalHost"/>.
86
- /// </summary>
87
49
  [JsonIgnore]
88
50
  public override string Host
89
51
  {
90
- get => ConnectionMode == ConnectionMode.Cloud ? CloudServerUrl : LocalHost;
52
+ get => LocalHost;
91
53
  set => LocalHost = value;
92
54
  }
93
55
 
94
- /// <summary>
95
- /// Gets/sets the active auth token based on <see cref="ConnectionMode"/>.
96
- /// In Cloud mode, routes to <see cref="CloudToken"/>.
97
- /// In Local mode, routes to <see cref="LocalToken"/>.
98
- /// Setter mirrors the getter so env-var / CLI overrides (which write via
99
- /// the generic Token property) land on the right field regardless of mode.
100
- /// </summary>
101
56
  [JsonIgnore]
102
57
  public override string? Token
103
58
  {
104
- get => ConnectionMode == ConnectionMode.Cloud ? CloudToken : LocalToken;
105
- set
106
- {
107
- if (ConnectionMode == ConnectionMode.Cloud)
108
- CloudToken = value;
109
- else
110
- LocalToken = value;
111
- }
59
+ get => LocalToken;
60
+ set => LocalToken = value;
112
61
  }
113
62
 
114
63
  public LogLevel LogLevel { get; set; } = LogLevel.Warning;
115
64
  public bool KeepServerRunning { get; set; } = false;
116
65
  public TransportMethod TransportMethod { get; set; } = TransportMethod.streamableHttp;
117
66
  public AuthOption AuthOption { get; set; } = AuthOption.none;
118
- public ConnectionMode ConnectionMode { get; set; } = ConnectionMode.Cloud;
67
+ public ConnectionMode ConnectionMode { get; set; } = ConnectionMode.Custom;
119
68
 
120
69
  /// <summary>
121
70
  /// Optional path to the Node.js MCP server entry script (cocli's bin/server.mjs).
@@ -165,7 +114,6 @@ namespace com.AtelierAI.Unity.Copilot
165
114
  /// <c>auth=none</c> (not recommended).
166
115
  /// </summary>
167
116
  public bool ForceTokenWhenLanBind { get; set; } = true;
168
- public string? CloudToken { get; set; }
169
117
  public List<CopilotFeature> Tools { get; set; } = new();
170
118
  public List<CopilotFeature> Prompts { get; set; } = new();
171
119
  public List<CopilotFeature> Resources { get; set; } = new();
@@ -191,9 +139,8 @@ namespace com.AtelierAI.Unity.Copilot
191
139
  KeepServerRunning = !isCi;
192
140
  TransportMethod = TransportMethod.streamableHttp;
193
141
  AuthOption = AuthOption.none;
194
- ConnectionMode = ConnectionMode.Cloud;
142
+ ConnectionMode = ConnectionMode.Custom;
195
143
  NodeServerPath = null;
196
- CloudToken = null;
197
144
  LogLevel = LogLevel.Warning;
198
145
  TimeoutMs = Consts.Hub.DefaultTimeoutMs;
199
146
  Tools = DefaultTools;
@@ -218,9 +165,11 @@ namespace com.AtelierAI.Unity.Copilot
218
165
  }
219
166
  }
220
167
 
168
+ /// <summary>Local/custom server connection. The legacy Cloud mode (remote
169
+ /// ai-game.dev endpoint) was removed in 1.0.3; configs that still carry
170
+ /// "Cloud" are mapped to Custom on load.</summary>
221
171
  public enum ConnectionMode
222
172
  {
223
- Custom,
224
- Cloud
173
+ Custom
225
174
  }
226
175
  }
@@ -26,7 +26,7 @@ namespace com.AtelierAI.Unity.Copilot
26
26
 
27
27
  public partial class UnityCopilotPlugin : IDisposable
28
28
  {
29
- public const string Version = "1.0.1";
29
+ public const string Version = "1.0.3";
30
30
 
31
31
  private static int _singletonCount = 0;
32
32
  public static bool HasAnyInstance => _singletonCount > 0;
@@ -47,7 +47,6 @@ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
47
47
  public const string EnvTools = "UNITY_MCP_TOOLS";
48
48
  public const string EnvStartServer = "UNITY_MCP_START_SERVER";
49
49
  public const string EnvTransport = "UNITY_MCP_TRANSPORT";
50
- public const string EnvCloudUrl = "UNITY_MCP_CLOUD_URL";
51
50
  public const string EnvConnectionMode = "UNITY_MCP_CONNECTION_MODE";
52
51
 
53
52
  // Short flag aliases recognised by the in-plugin command-line parser.
@@ -64,7 +63,6 @@ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
64
63
  public const string FieldKeepConnected = nameof(UnityCopilotPlugin.UnityConnectionConfig.KeepConnected);
65
64
  public const string FieldAuthOption = nameof(UnityCopilotPlugin.UnityConnectionConfig.AuthOption);
66
65
  public const string FieldLocalToken = nameof(UnityCopilotPlugin.UnityConnectionConfig.LocalToken);
67
- public const string FieldCloudToken = nameof(UnityCopilotPlugin.UnityConnectionConfig.CloudToken);
68
66
  public const string FieldTools = nameof(UnityCopilotPlugin.UnityConnectionConfig.EnabledToolsOverride);
69
67
  public const string FieldStartServer = nameof(UnityCopilotPlugin.UnityConnectionConfig.KeepServerRunning);
70
68
  public const string FieldTransport = nameof(UnityCopilotPlugin.UnityConnectionConfig.TransportMethod);
@@ -176,9 +174,9 @@ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
176
174
 
177
175
  string Sanitize(string raw) => raw.Trim().Trim('"');
178
176
 
179
- // UNITY_MCP_HOST is the legacy alias for UNITY_MCP_CLOUD_URL.
177
+ // UNITY_MCP_HOST / --url override the local server host.
180
178
  string? sanitizedHost = null;
181
- var rawHost = Resolve(EnvCloudUrl, FlagUrl) ?? Resolve(EnvHost, flagAlias: null);
179
+ var rawHost = Resolve(EnvHost, FlagUrl);
182
180
  if (rawHost != null)
183
181
  {
184
182
  var host = Sanitize(rawHost).TrimEnd('/');
@@ -231,8 +229,7 @@ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
231
229
  _logger.LogInformation("[MCP] Override: {Key}={Value}", EnvAuthOption, ao);
232
230
  }
233
231
 
234
- // Resolved AFTER ConnectionMode so we route to the correct underlying field
235
- // (LocalToken in Custom mode, CloudToken in Cloud mode). We track the specific
232
+ // We track the specific
236
233
  // backing field rather than the abstract Token property because only the backing
237
234
  // fields are serialised — restoring the baseline must target the same field that
238
235
  // was clobbered.
@@ -240,23 +237,11 @@ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
240
237
  if (rawToken != null)
241
238
  {
242
239
  var token = Sanitize(rawToken);
243
- if (config.ConnectionMode == ConnectionMode.Cloud)
240
+ if (!string.Equals(token, config.LocalToken, StringComparison.Ordinal))
244
241
  {
245
- if (!string.Equals(token, config.CloudToken, StringComparison.Ordinal))
246
- {
247
- record.Track(FieldCloudToken, config.CloudToken, token);
248
- config.CloudToken = token;
249
- _logger.LogInformation("[MCP] Override: {Key}=*** (CloudToken)", EnvToken);
250
- }
251
- }
252
- else
253
- {
254
- if (!string.Equals(token, config.LocalToken, StringComparison.Ordinal))
255
- {
256
- record.Track(FieldLocalToken, config.LocalToken, token);
257
- config.LocalToken = token;
258
- _logger.LogInformation("[MCP] Override: {Key}=*** (LocalToken)", EnvToken);
259
- }
242
+ record.Track(FieldLocalToken, config.LocalToken, token);
243
+ config.LocalToken = token;
244
+ _logger.LogInformation("[MCP] Override: {Key}=*** (LocalToken)", EnvToken);
260
245
  }
261
246
  }
262
247
 
@@ -341,9 +326,6 @@ namespace com.AtelierAI.Unity.Copilot.Runtime.Utils
341
326
  case FieldLocalToken:
342
327
  config.LocalToken = (string?)kvp.Value;
343
328
  break;
344
- case FieldCloudToken:
345
- config.CloudToken = (string?)kvp.Value;
346
- break;
347
329
  case FieldTools:
348
330
  config.EnabledToolsOverride = (List<string>?)kvp.Value;
349
331
  break;