@atelierai/uco 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -8
- package/package.json +2 -2
- package/vendor/plugin/com.atelierai.unity.copilot/CHANGELOG.md +4 -4
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/ToolGroups.SetEnabled.cs +92 -92
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +0 -147
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.Editor.cs +16 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotServer.cs +3 -3
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolGroupRegistry.cs +461 -460
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/CopilotPromptsWindow.uss +11 -11
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/CopilotResourcesWindow.uss +16 -16
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/CopilotToolsWindow.uss +36 -36
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/MainWindow.uss +183 -183
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/common/{_mcp-list-window.uss → _copilot-list-window.uss} +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/common/_list-view.uss +77 -77
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/CopilotPromptsWindow.uxml +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/CopilotResourcesWindow.uxml +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/CopilotToolsWindow.uxml +18 -18
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uxml/MainWindow.uxml +115 -115
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/ReflectorNet.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.Common.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/README.md +88 -88
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/BufferedFileLogStorage.cs +208 -207
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/FileLogStorage.cs +3 -1
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/UnityLogCollector.cs +282 -280
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.cs +1 -1
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetExtractorDevelopmentDependencyTests.cs +148 -148
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetExtractorFlatLayoutTests.cs +166 -166
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetInstallManifestTests.cs +436 -436
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetLegacyMigrationTests.cs +1 -1
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetPackageInstallerStaleVersionCleanupTests.cs +200 -200
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +1 -1
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/GameObject/TestJsonSchema.cs +199 -199
- package/vendor/plugin/com.atelierai.unity.copilot/package.json +1 -1
- /package/vendor/plugin/com.atelierai.unity.copilot/Editor/UI/uss/common/{_mcp-list-window.uss.meta → _copilot-list-window.uss.meta} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.10 - 2026-09-19
|
|
4
|
+
|
|
5
|
+
- Vendored plugin refreshed to **1.0.8** — fixes an editor-native crash on
|
|
6
|
+
domain reload (UmaViewer issue uco-domain-reload-crash-20260919, 2/2
|
|
7
|
+
reproducible during script recompile). The plugin no longer defines a
|
|
8
|
+
finalizer: the historical one ran the full teardown (token cancellation
|
|
9
|
+
with synchronous Task continuations and ExecutionContext restores) on the
|
|
10
|
+
GC finalizer thread during domain unload, which mono cannot execute.
|
|
11
|
+
Assembly-reload/unload/quit cleanup now disposes the plugin instance
|
|
12
|
+
deterministically on the safe background-thread path. Ten other
|
|
13
|
+
same-pattern finalizers (request DTOs, log storage/collector) removed with
|
|
14
|
+
it. Framework tests 831x2; 2022.3 gate unchanged.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## 1.0.9 - 2026-09-19
|
|
18
|
+
|
|
19
|
+
- Vendored plugin refreshed to **1.0.7**: the complete legacy-naming sweep —
|
|
20
|
+
dead config-builder helpers removed (the last code producing
|
|
21
|
+
agent-config-shaped JSON), internal docs rewritten to the current
|
|
22
|
+
architecture, package/UI naming cleaned end to end, and a live prefs-key
|
|
23
|
+
bug fixed (the tool-group flag now reads the key its own migration writes).
|
|
24
|
+
Framework tests 831x2, 2022.3 gate 857/858 unchanged.
|
|
25
|
+
|
|
26
|
+
|
|
3
27
|
## 1.0.8 - 2026-09-19
|
|
4
28
|
|
|
5
29
|
- Vendored plugin refreshed to **1.0.6**: the C# source's internal type and
|
|
@@ -14,10 +38,10 @@
|
|
|
14
38
|
## 1.0.7 - 2026-09-19
|
|
15
39
|
|
|
16
40
|
- **Legacy agent-config writing removed.** uco no longer writes or
|
|
17
|
-
reconciles server entries into agent-client config files
|
|
41
|
+
reconciles server entries into agent-client config files
|
|
18
42
|
Cursor, codex toml, …) — those entries pointed at a protocol surface the
|
|
19
43
|
bridge has never spoken and never worked; they only surfaced as dead
|
|
20
|
-
entries in agent tooling.
|
|
44
|
+
entries in agent tooling. The legacy setup and login commands are gone.
|
|
21
45
|
Existing entries in your projects are left untouched; delete them at will.
|
|
22
46
|
- **Legacy naming surface scrubbed end to end.** The bridge speaks plain
|
|
23
47
|
REST (`/api/*`) plus a raw-WebSocket plugin hub — nothing else — and the
|
|
@@ -34,7 +58,7 @@
|
|
|
34
58
|
|
|
35
59
|
## 1.0.6 - 2026-09-19
|
|
36
60
|
|
|
37
|
-
- Agent
|
|
61
|
+
- Agent-client config files written by the legacy setup command /
|
|
38
62
|
`uco update` now dial `127.0.0.1` even when the project config's host says
|
|
39
63
|
`localhost` — third-party agent clients (Claude Code, codex) run on Node
|
|
40
64
|
runtimes that resolve `localhost` to `::1`, which per-process proxy rules
|
|
@@ -54,8 +78,8 @@
|
|
|
54
78
|
(Node's fetch may resolve `localhost` to ::1, which proxy rules matching
|
|
55
79
|
node.exe commonly hijack), and a dead bridge behind such a proxy still
|
|
56
80
|
classifies as `connection-refused` instead of an opaque `fetch failed`.
|
|
57
|
-
`uco open --start-server` handoff health checks and generated
|
|
58
|
-
|
|
81
|
+
`uco open --start-server` handoff health checks and generated agent configs use
|
|
82
|
+
`127.0.0.1` as well.
|
|
59
83
|
- Legacy `.cocli-skill.json` markers refresh in place again (a pre-rename
|
|
60
84
|
install was refused by its own ownership marker; the marker file itself
|
|
61
85
|
no longer counts as unmanaged).
|
|
@@ -68,7 +92,7 @@
|
|
|
68
92
|
|
|
69
93
|
## 1.0.4 - 2026-09-17
|
|
70
94
|
|
|
71
|
-
- Server startup banner says "uco bridge"
|
|
95
|
+
- Server startup banner says "uco bridge"; help
|
|
72
96
|
endpoint header updated to match.
|
|
73
97
|
- Vendored plugin refreshed to **1.0.4**: the in-editor updater now
|
|
74
98
|
detects embedded installs (uco install) and directs the user to the
|
|
@@ -81,7 +105,7 @@
|
|
|
81
105
|
bridge discovery now finds the published **@atelierai/uco** npm package
|
|
82
106
|
(plus legacy `uco`/`cocli` layouts as fallbacks).
|
|
83
107
|
- Help text and skill templates say "uco bridge server" instead of
|
|
84
|
-
|
|
108
|
+
the legacy server name; the uco-setup recovery skill now documents how to
|
|
85
109
|
bring the bridge up (`uco open --start-server true`, plugin auto-start,
|
|
86
110
|
manual spawn with the exact CLI arguments).
|
|
87
111
|
|
|
@@ -90,7 +114,7 @@
|
|
|
90
114
|
- Product naming unified to **Unity Copilot** (no hyphen) across docs and
|
|
91
115
|
skill templates.
|
|
92
116
|
- Vendored plugin refreshed to **1.0.2**: one menu tree (Tools ▸ Unity
|
|
93
|
-
Copilot), the "AI Game Developer" leftovers and the dead
|
|
117
|
+
Copilot), the "AI Game Developer" leftovers and the dead legacy inspector
|
|
94
118
|
item removed.
|
|
95
119
|
- `uco init` interactive agent selection now renders a checkbox list
|
|
96
120
|
(space toggles, arrows move, enter confirms) on a TTY; non-TTY keeps the
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atelierai/uco",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "uco — Unity Copilot CLI. Drive Unity Editor (and runtime game builds) from any AI agent via plain HTTP.
|
|
3
|
+
"version": "1.0.10",
|
|
4
|
+
"description": "uco — Unity Copilot CLI. Drive Unity Editor (and runtime game builds) from any AI agent via plain HTTP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"uco": "./bin/uco.mjs",
|
|
@@ -22,7 +22,7 @@ detects the embedded layout and directs the user to run
|
|
|
22
22
|
Discovery now probes @atelierai/uco, then the legacy uco and cocli layouts,
|
|
23
23
|
project-local and npm-global.
|
|
24
24
|
- Token env overrides route straight to the local token (no mode routing);
|
|
25
|
-
|
|
25
|
+
the cloud URL variable is gone; --url and the host variable keep working.
|
|
26
26
|
|
|
27
27
|
## [1.0.2] - 2026-09-15 — one menu tree, one name: Unity Copilot
|
|
28
28
|
|
|
@@ -32,9 +32,9 @@ detects the embedded layout and directs the user to run
|
|
|
32
32
|
- The leftover "AI Game Developer" menu tree (NuGet resolver items) is
|
|
33
33
|
merged into **Tools ▸ Unity Copilot**; the stray root-level
|
|
34
34
|
"Generate Tools Manifest" item moves under it too.
|
|
35
|
-
- Removed the dead **
|
|
36
|
-
`Commands/` folder (`
|
|
37
|
-
bridge speaks plain REST,
|
|
35
|
+
- Removed the dead **legacy inspector** menu item and the legacy
|
|
36
|
+
`Commands/` folder (`start_legacy_inspector.bat`, `copy_readme.bat`) — the
|
|
37
|
+
bridge speaks plain REST, with no endpoint of that kind to inspect.
|
|
38
38
|
- Team update kill-switch asset renamed to
|
|
39
39
|
`ProjectSettings/Copilot-UpdateSettings.asset` (the old
|
|
40
40
|
AI-Game-Developer-named file is no longer read; the toggle resets to
|
package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/ToolGroups.SetEnabled.cs
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Design inspired by MCP for Unity (CoplayDev/unity-mcp), Copyright (c) Coplay Inc., MIT License.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/*
|
|
6
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
7
|
-
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
8
|
-
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
9
|
-
│ Copyright (c) 2025 Ivan Murzak │
|
|
10
|
-
│ Licensed under the Apache License, Version 2.0. │
|
|
11
|
-
│ See the LICENSE file in the project root for more information. │
|
|
12
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
#nullable enable
|
|
16
|
-
using System;
|
|
17
|
-
using System.ComponentModel;
|
|
18
|
-
using AIGD;
|
|
19
|
-
using com.AtelierAI.Uco.Framework;
|
|
20
|
-
using com.IvanMurzak.ReflectorNet.Utils;
|
|
21
|
-
using com.AtelierAI.Unity.Copilot.Editor.Utils;
|
|
22
|
-
|
|
23
|
-
namespace com.AtelierAI.Unity.Copilot.Editor.API
|
|
24
|
-
{
|
|
25
|
-
public partial class Tool_ToolGroups
|
|
26
|
-
{
|
|
27
|
-
public const string ToolsSetGroupEnabledId = "tools-set-group-enabled";
|
|
28
|
-
|
|
29
|
-
[UcoTool
|
|
30
|
-
(
|
|
31
|
-
ToolsSetGroupEnabledId,
|
|
32
|
-
Title = "Tools / Set Group Enabled",
|
|
33
|
-
DestructiveHint = true
|
|
34
|
-
)]
|
|
35
|
-
[UcoSkillDescription("Enable or disable an uco tool group at runtime, persisting the choice to EditorPrefs. " +
|
|
36
|
-
"Use this together with 'tools-list-groups' to keep the LLM tool-list lean: turn off niche groups " +
|
|
37
|
-
"(physics, profiler, vfx) until you need them. " +
|
|
38
|
-
"NOTE: currently a soft hint — disabled tools remain callable; enforcement requires hooking the request pipeline.")]
|
|
39
|
-
[UcoSkillBody("Toggle a logical tool group. " +
|
|
40
|
-
"Groups are declared on `Tool_*` partial-class roots via `[ToolGroupAttribute(\"name\")]`. " +
|
|
41
|
-
"This tool only updates the registry + EditorPrefs; it does not modify the upstream NuGet package " +
|
|
42
|
-
"or hook `IRunTool.RunCallTool`, so toggling is informational only at the moment.\n\n" +
|
|
43
|
-
"## Inputs\n\n" +
|
|
44
|
-
"- `group` — group name (case-sensitive). Use `tools-list-groups` to discover valid names.\n" +
|
|
45
|
-
"- `enabled` — true to enable the group, false to disable.\n\n" +
|
|
46
|
-
"## Persistence\n\n" +
|
|
47
|
-
"Stored under EditorPrefs key
|
|
48
|
-
"`group=0|group=1` string. Stale entries (for groups that no longer exist) are ignored on load.")]
|
|
49
|
-
[Description("Enable or disable an uco tool group at runtime, persisting the choice to EditorPrefs. " +
|
|
50
|
-
"Soft hint only — disabled tools remain callable through the upstream request pipeline.")]
|
|
51
|
-
public ToolGroupResult SetGroupEnabled
|
|
52
|
-
(
|
|
53
|
-
[Description("Group name. Use 'tools-list-groups' to discover valid group names.")]
|
|
54
|
-
string group,
|
|
55
|
-
[Description("True to enable the group, false to disable it.")]
|
|
56
|
-
bool enabled
|
|
57
|
-
)
|
|
58
|
-
{
|
|
59
|
-
if (string.IsNullOrWhiteSpace(group))
|
|
60
|
-
throw new ArgumentException(Error.GroupNameIsEmpty(), nameof(group));
|
|
61
|
-
|
|
62
|
-
return MainThread.Instance.Run(() =>
|
|
63
|
-
{
|
|
64
|
-
var canonicalGroup = ToolGroupRegistry.ResolveCanonicalGroup(group);
|
|
65
|
-
if (canonicalGroup == null)
|
|
66
|
-
throw new ArgumentException(Error.UnknownGroup(group), nameof(group));
|
|
67
|
-
|
|
68
|
-
var previous = ToolGroupRegistry.IsGroupEnabled(canonicalGroup);
|
|
69
|
-
if (previous != enabled)
|
|
70
|
-
ToolGroupRegistry.SetGroupEnabled(canonicalGroup, enabled);
|
|
71
|
-
|
|
72
|
-
var tools = ToolGroupRegistry.ToolsInGroup(canonicalGroup);
|
|
73
|
-
var aliases = ToolGroupRegistry.AliasesForGroup(canonicalGroup);
|
|
74
|
-
var aliasesArray = new string[aliases.Count];
|
|
75
|
-
for (var i = 0; i < aliases.Count; i++) aliasesArray[i] = aliases[i];
|
|
76
|
-
|
|
77
|
-
return new ToolGroupResult
|
|
78
|
-
{
|
|
79
|
-
Group = canonicalGroup,
|
|
80
|
-
Enabled = enabled,
|
|
81
|
-
RequestedEnabled = enabled,
|
|
82
|
-
EffectiveEnabled = ToolGroupRegistry.IsGroupEffectivelyEnabled(canonicalGroup),
|
|
83
|
-
Aliases = aliasesArray,
|
|
84
|
-
PreviousEnabled = previous,
|
|
85
|
-
Changed = previous != enabled,
|
|
86
|
-
ToolCount = tools.Count,
|
|
87
|
-
Note = SoftHintNote
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Design inspired by MCP for Unity (CoplayDev/unity-mcp), Copyright (c) Coplay Inc., MIT License.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
7
|
+
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
8
|
+
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
9
|
+
│ Copyright (c) 2025 Ivan Murzak │
|
|
10
|
+
│ Licensed under the Apache License, Version 2.0. │
|
|
11
|
+
│ See the LICENSE file in the project root for more information. │
|
|
12
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#nullable enable
|
|
16
|
+
using System;
|
|
17
|
+
using System.ComponentModel;
|
|
18
|
+
using AIGD;
|
|
19
|
+
using com.AtelierAI.Uco.Framework;
|
|
20
|
+
using com.IvanMurzak.ReflectorNet.Utils;
|
|
21
|
+
using com.AtelierAI.Unity.Copilot.Editor.Utils;
|
|
22
|
+
|
|
23
|
+
namespace com.AtelierAI.Unity.Copilot.Editor.API
|
|
24
|
+
{
|
|
25
|
+
public partial class Tool_ToolGroups
|
|
26
|
+
{
|
|
27
|
+
public const string ToolsSetGroupEnabledId = "tools-set-group-enabled";
|
|
28
|
+
|
|
29
|
+
[UcoTool
|
|
30
|
+
(
|
|
31
|
+
ToolsSetGroupEnabledId,
|
|
32
|
+
Title = "Tools / Set Group Enabled",
|
|
33
|
+
DestructiveHint = true
|
|
34
|
+
)]
|
|
35
|
+
[UcoSkillDescription("Enable or disable an uco tool group at runtime, persisting the choice to EditorPrefs. " +
|
|
36
|
+
"Use this together with 'tools-list-groups' to keep the LLM tool-list lean: turn off niche groups " +
|
|
37
|
+
"(physics, profiler, vfx) until you need them. " +
|
|
38
|
+
"NOTE: currently a soft hint — disabled tools remain callable; enforcement requires hooking the request pipeline.")]
|
|
39
|
+
[UcoSkillBody("Toggle a logical tool group. " +
|
|
40
|
+
"Groups are declared on `Tool_*` partial-class roots via `[ToolGroupAttribute(\"name\")]`. " +
|
|
41
|
+
"This tool only updates the registry + EditorPrefs; it does not modify the upstream NuGet package " +
|
|
42
|
+
"or hook `IRunTool.RunCallTool`, so toggling is informational only at the moment.\n\n" +
|
|
43
|
+
"## Inputs\n\n" +
|
|
44
|
+
"- `group` — group name (case-sensitive). Use `tools-list-groups` to discover valid names.\n" +
|
|
45
|
+
"- `enabled` — true to enable the group, false to disable.\n\n" +
|
|
46
|
+
"## Persistence\n\n" +
|
|
47
|
+
"Stored under the product EditorPrefs key `<prefix>.ToolGroups.Enabled` as a pipe-separated " +
|
|
48
|
+
"`group=0|group=1` string. Stale entries (for groups that no longer exist) are ignored on load.")]
|
|
49
|
+
[Description("Enable or disable an uco tool group at runtime, persisting the choice to EditorPrefs. " +
|
|
50
|
+
"Soft hint only — disabled tools remain callable through the upstream request pipeline.")]
|
|
51
|
+
public ToolGroupResult SetGroupEnabled
|
|
52
|
+
(
|
|
53
|
+
[Description("Group name. Use 'tools-list-groups' to discover valid group names.")]
|
|
54
|
+
string group,
|
|
55
|
+
[Description("True to enable the group, false to disable it.")]
|
|
56
|
+
bool enabled
|
|
57
|
+
)
|
|
58
|
+
{
|
|
59
|
+
if (string.IsNullOrWhiteSpace(group))
|
|
60
|
+
throw new ArgumentException(Error.GroupNameIsEmpty(), nameof(group));
|
|
61
|
+
|
|
62
|
+
return MainThread.Instance.Run(() =>
|
|
63
|
+
{
|
|
64
|
+
var canonicalGroup = ToolGroupRegistry.ResolveCanonicalGroup(group);
|
|
65
|
+
if (canonicalGroup == null)
|
|
66
|
+
throw new ArgumentException(Error.UnknownGroup(group), nameof(group));
|
|
67
|
+
|
|
68
|
+
var previous = ToolGroupRegistry.IsGroupEnabled(canonicalGroup);
|
|
69
|
+
if (previous != enabled)
|
|
70
|
+
ToolGroupRegistry.SetGroupEnabled(canonicalGroup, enabled);
|
|
71
|
+
|
|
72
|
+
var tools = ToolGroupRegistry.ToolsInGroup(canonicalGroup);
|
|
73
|
+
var aliases = ToolGroupRegistry.AliasesForGroup(canonicalGroup);
|
|
74
|
+
var aliasesArray = new string[aliases.Count];
|
|
75
|
+
for (var i = 0; i < aliases.Count; i++) aliasesArray[i] = aliases[i];
|
|
76
|
+
|
|
77
|
+
return new ToolGroupResult
|
|
78
|
+
{
|
|
79
|
+
Group = canonicalGroup,
|
|
80
|
+
Enabled = enabled,
|
|
81
|
+
RequestedEnabled = enabled,
|
|
82
|
+
EffectiveEnabled = ToolGroupRegistry.IsGroupEffectivelyEnabled(canonicalGroup),
|
|
83
|
+
Aliases = aliasesArray,
|
|
84
|
+
PreviousEnabled = previous,
|
|
85
|
+
Changed = previous != enabled,
|
|
86
|
+
ToolCount = tools.Count,
|
|
87
|
+
Note = SoftHintNote
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -222,153 +222,6 @@ namespace com.AtelierAI.Unity.Copilot.Editor
|
|
|
222
222
|
|
|
223
223
|
#endregion // Node Server Discovery
|
|
224
224
|
|
|
225
|
-
#region Client Configuration
|
|
226
|
-
|
|
227
|
-
/// <summary>
|
|
228
|
-
/// Generates a JSON configuration for stdio transport.
|
|
229
|
-
/// <code>
|
|
230
|
-
/// {
|
|
231
|
-
/// "mcpServers": {
|
|
232
|
-
/// "Unity ProjectName": {
|
|
233
|
-
/// "type": "...", // optional, only if provided
|
|
234
|
-
/// "command": "node",
|
|
235
|
-
/// "args": ["path/to/bin/server.mjs", "--port", "...", "--plugin-timeout-ms", "...", "--authorization", "..." /*, "--token", "..." if auth required */]
|
|
236
|
-
/// }
|
|
237
|
-
/// }
|
|
238
|
-
/// }
|
|
239
|
-
/// </code>
|
|
240
|
-
/// </summary>
|
|
241
|
-
public static JsonNode RawJsonConfigurationStdio(
|
|
242
|
-
int port,
|
|
243
|
-
string bodyPath = "mcpServers",
|
|
244
|
-
int timeoutMs = Consts.Hub.DefaultTimeoutMs,
|
|
245
|
-
string? type = null)
|
|
246
|
-
{
|
|
247
|
-
var pathSegments = BodyPathSegments(bodyPath);
|
|
248
|
-
|
|
249
|
-
// Build innermost content first
|
|
250
|
-
var serverConfig = new JsonObject();
|
|
251
|
-
|
|
252
|
-
if (type != null)
|
|
253
|
-
serverConfig["type"] = type;
|
|
254
|
-
|
|
255
|
-
// The AI agent launches the Node.js Uco server via the node runtime.
|
|
256
|
-
// When the entry script cannot be resolved right now, fall back to the
|
|
257
|
-
// documented project-local install location so the generated config is
|
|
258
|
-
// still a valid, copy-pasteable starting point.
|
|
259
|
-
var serverEntry = ResolveNodeServerEntry()
|
|
260
|
-
?? Path.Combine("node_modules", NodeServerPackageNames[0], NodeServerEntryRelativePath);
|
|
261
|
-
|
|
262
|
-
serverConfig["command"] = ResolveNodeExecutable().Replace('\\', '/');
|
|
263
|
-
|
|
264
|
-
var args = new JsonArray
|
|
265
|
-
{
|
|
266
|
-
serverEntry.Replace('\\', '/'),
|
|
267
|
-
"--port",
|
|
268
|
-
port.ToString(),
|
|
269
|
-
"--plugin-timeout-ms",
|
|
270
|
-
timeoutMs.ToString(),
|
|
271
|
-
"--authorization",
|
|
272
|
-
UnityCopilotPluginEditor.AuthOption.ToString()
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
var authRequired = UnityCopilotPluginEditor.AuthOption == AuthOption.required;
|
|
276
|
-
if (authRequired && !string.IsNullOrEmpty(UnityCopilotPluginEditor.Token))
|
|
277
|
-
{
|
|
278
|
-
args.Add("--token");
|
|
279
|
-
args.Add(UnityCopilotPluginEditor.Token);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
serverConfig["args"] = args;
|
|
283
|
-
|
|
284
|
-
var innerContent = new JsonObject
|
|
285
|
-
{
|
|
286
|
-
["ai-game-developer"] = serverConfig
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
// Build nested structure from innermost to outermost
|
|
290
|
-
var result = innerContent;
|
|
291
|
-
for (int i = pathSegments.Length - 1; i >= 0; i--)
|
|
292
|
-
{
|
|
293
|
-
result = new JsonObject { [pathSegments[i]] = result };
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return result;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/// <summary>
|
|
300
|
-
/// Generates a JSON configuration for HTTP transport.
|
|
301
|
-
/// <code>
|
|
302
|
-
/// {
|
|
303
|
-
/// "mcpServers": {
|
|
304
|
-
/// "Unity ProjectName": {
|
|
305
|
-
/// "type": "...", // optional, only if provided
|
|
306
|
-
/// "url": "http://localhost:port",
|
|
307
|
-
/// "headers": { // only if token is provided
|
|
308
|
-
/// "Authorization": "Bearer token"
|
|
309
|
-
/// }
|
|
310
|
-
/// }
|
|
311
|
-
/// }
|
|
312
|
-
/// }
|
|
313
|
-
/// </code>
|
|
314
|
-
/// </summary>
|
|
315
|
-
public static JsonNode RawJsonConfigurationHttp(
|
|
316
|
-
string url,
|
|
317
|
-
string bodyPath = "mcpServers",
|
|
318
|
-
string? type = null)
|
|
319
|
-
{
|
|
320
|
-
// ── Safe-defaults advisory ────────────────────────────────────────────────
|
|
321
|
-
// If the URL targets a remote host over plain HTTP and the user has not opted in
|
|
322
|
-
// to insecure remote HTTP, log a single warning. We deliberately do NOT throw or
|
|
323
|
-
// rewrite the URL here — the configurators are expected to produce *some* output
|
|
324
|
-
// even when the configuration is sub-optimal, so the user can see what was
|
|
325
|
-
// generated and decide. The dialog/UI gate handles refusal at start time.
|
|
326
|
-
if (SafeDefaultsGuard.IsInsecureRemoteHttpUrl(url) &&
|
|
327
|
-
!UnityCopilotPluginEditor.AllowInsecureRemoteHttp)
|
|
328
|
-
{
|
|
329
|
-
_logger.LogWarning(
|
|
330
|
-
"Generating AI agent client config for plain-HTTP remote URL '{url}' without " +
|
|
331
|
-
"AllowInsecureRemoteHttp. The token (if any) and tool payloads will be " +
|
|
332
|
-
"sent unencrypted. Either switch to https:// or enable 'Allow Insecure " +
|
|
333
|
-
"Remote HTTP' in the Game Developer window to silence this warning.",
|
|
334
|
-
url);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
var pathSegments = BodyPathSegments(bodyPath);
|
|
338
|
-
|
|
339
|
-
// Build innermost content first
|
|
340
|
-
var serverConfig = new JsonObject();
|
|
341
|
-
|
|
342
|
-
if (type != null)
|
|
343
|
-
serverConfig["type"] = type;
|
|
344
|
-
|
|
345
|
-
serverConfig["url"] = url;
|
|
346
|
-
|
|
347
|
-
var authRequired = UnityCopilotPluginEditor.AuthOption == AuthOption.required;
|
|
348
|
-
if (authRequired && !string.IsNullOrEmpty(UnityCopilotPluginEditor.Token))
|
|
349
|
-
{
|
|
350
|
-
serverConfig["headers"] = new JsonObject
|
|
351
|
-
{
|
|
352
|
-
["Authorization"] = $"Bearer {UnityCopilotPluginEditor.Token}"
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
var innerContent = new JsonObject
|
|
357
|
-
{
|
|
358
|
-
["ai-game-developer"] = serverConfig
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
// Build nested structure from innermost to outermost
|
|
362
|
-
var result = innerContent;
|
|
363
|
-
for (int i = pathSegments.Length - 1; i >= 0; i--)
|
|
364
|
-
{
|
|
365
|
-
result = new JsonObject { [pathSegments[i]] = result };
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
return result;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
#endregion // Client Configuration
|
|
372
225
|
|
|
373
226
|
#region Process Lifecycle
|
|
374
227
|
|
|
@@ -84,6 +84,22 @@ namespace com.AtelierAI.Unity.Copilot.Editor
|
|
|
84
84
|
nameof(Startup), callerName, e.Message);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
|
|
88
|
+
// Deterministic teardown on reload/unload/quit: dispose the plugin
|
|
89
|
+
// instance on a background thread (the safe context for the token
|
|
90
|
+
// cancellation callbacks — same reasoning as
|
|
91
|
+
// DisposeUcoPluginInstance). Without this, the instance survived
|
|
92
|
+
// domain unload undisposed and relied on GC finalization — the
|
|
93
|
+
// crash path fixed in uco-domain-reload-crash-20260919.
|
|
94
|
+
try
|
|
95
|
+
{
|
|
96
|
+
plugin.DisposeUcoPluginInstance();
|
|
97
|
+
}
|
|
98
|
+
catch (System.Exception e)
|
|
99
|
+
{
|
|
100
|
+
_logger.LogWarning(e, "{class} {method}: Exception during plugin disposal (non-blocking): {message}",
|
|
101
|
+
nameof(Startup), callerName, e.Message);
|
|
102
|
+
}
|
|
87
103
|
}
|
|
88
104
|
|
|
89
105
|
try
|
|
@@ -28,10 +28,10 @@ namespace com.AtelierAI.Unity.Copilot.Editor.UI
|
|
|
28
28
|
private void SetupServerSection(VisualElement root)
|
|
29
29
|
{
|
|
30
30
|
var btnStartStop = root.Q<Button>("btnStartStopServer") ?? throw new InvalidOperationException("Server start/stop button not found.");
|
|
31
|
-
var statusCircle = root.Q<VisualElement>("
|
|
32
|
-
var statusLabel = root.Q<Label>("
|
|
31
|
+
var statusCircle = root.Q<VisualElement>("serverStatusCircle") ?? throw new InvalidOperationException("Server status circle not found.");
|
|
32
|
+
var statusLabel = root.Q<Label>("serverLabel") ?? throw new InvalidOperationException("Server status label not found.");
|
|
33
33
|
|
|
34
|
-
var timelinePointServer = root.Q<VisualElement>("
|
|
34
|
+
var timelinePointServer = root.Q<VisualElement>("TimelinePointServer");
|
|
35
35
|
if (timelinePointServer != null)
|
|
36
36
|
timelinePointServer.tooltip = Tooltip_ServerTimelineLabel;
|
|
37
37
|
statusCircle.tooltip = Tooltip_ServerTimelineLabel;
|