@mflrevan/ucp 0.2.0 → 0.2.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 (66) hide show
  1. package/README.md +3 -3
  2. package/bridge/com.ucp.bridge/CHANGELOG.md +56 -0
  3. package/bridge/com.ucp.bridge/CHANGELOG.md.meta +7 -0
  4. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +573 -0
  5. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs.meta +2 -0
  6. package/bridge/com.ucp.bridge/Editor/Bridge.meta +8 -0
  7. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +499 -0
  8. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs.meta +2 -0
  9. package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs +230 -0
  10. package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs.meta +2 -0
  11. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +26 -0
  12. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs.meta +2 -0
  13. package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs +435 -0
  14. package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs.meta +2 -0
  15. package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs +130 -0
  16. package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs.meta +2 -0
  17. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +319 -0
  18. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs.meta +2 -0
  19. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +291 -0
  20. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs.meta +2 -0
  21. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +295 -0
  22. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs.meta +2 -0
  23. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +38 -0
  24. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs.meta +2 -0
  25. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +242 -0
  26. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs.meta +2 -0
  27. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +551 -0
  28. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs.meta +2 -0
  29. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +70 -0
  30. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs.meta +2 -0
  31. package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs +125 -0
  32. package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs.meta +2 -0
  33. package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs +104 -0
  34. package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs.meta +2 -0
  35. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +227 -0
  36. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs.meta +2 -0
  37. package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +180 -0
  38. package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs.meta +2 -0
  39. package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs +611 -0
  40. package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs.meta +2 -0
  41. package/bridge/com.ucp.bridge/Editor/Controllers.meta +8 -0
  42. package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs +45 -0
  43. package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs.meta +2 -0
  44. package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs +80 -0
  45. package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs.meta +2 -0
  46. package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +358 -0
  47. package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs.meta +2 -0
  48. package/bridge/com.ucp.bridge/Editor/Protocol.meta +8 -0
  49. package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs +37 -0
  50. package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs.meta +2 -0
  51. package/bridge/com.ucp.bridge/Editor/Scripts.meta +8 -0
  52. package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef +16 -0
  53. package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef.meta +7 -0
  54. package/bridge/com.ucp.bridge/Editor.meta +8 -0
  55. package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +14 -0
  56. package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +7 -0
  57. package/bridge/com.ucp.bridge/Runtime.meta +8 -0
  58. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +194 -0
  59. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs.meta +2 -0
  60. package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef +12 -0
  61. package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef.meta +7 -0
  62. package/bridge/com.ucp.bridge/Tests/Editor.meta +8 -0
  63. package/bridge/com.ucp.bridge/Tests.meta +8 -0
  64. package/bridge/com.ucp.bridge/package.json +27 -0
  65. package/bridge/com.ucp.bridge/package.json.meta +7 -0
  66. package/package.json +1 -1
@@ -0,0 +1,194 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using NUnit.Framework;
4
+ using UnityEditor;
5
+ using UnityEditor.SceneManagement;
6
+ using UnityEngine;
7
+
8
+ namespace UCP.Bridge.Tests
9
+ {
10
+ public class ControllerSmokeTests
11
+ {
12
+ private const string TempAssetPath = "Assets/UcpControllerSmoke.asset";
13
+
14
+ private CommandRouter _router;
15
+
16
+ [SetUp]
17
+ public void SetUp()
18
+ {
19
+ _router = new CommandRouter();
20
+ SnapshotController.Register(_router);
21
+ AssetController.Register(_router);
22
+ LogsController.Register(_router);
23
+ EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
24
+ DeleteTempAsset();
25
+ LogsController.ClearHistoryForTests();
26
+ }
27
+
28
+ [TearDown]
29
+ public void TearDown()
30
+ {
31
+ DeleteTempAsset();
32
+ LogsController.ClearHistoryForTests();
33
+ EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
34
+ }
35
+
36
+ [Test]
37
+ public void Snapshot_DefaultDepth_ReturnsLeanRootMetadata()
38
+ {
39
+ var root = new GameObject("Root");
40
+ var child = new GameObject("Child");
41
+ child.transform.SetParent(root.transform, false);
42
+
43
+ var response = _router.Dispatch("snapshot", 1, "{\"depth\":0}");
44
+
45
+ Assert.That(response.error, Is.Null);
46
+
47
+ var result = (Dictionary<string, object>)response.result;
48
+ var objects = (List<object>)result["objects"];
49
+ Assert.That(objects.Count, Is.EqualTo(1));
50
+
51
+ var entry = (Dictionary<string, object>)objects[0];
52
+ Assert.That(entry["name"], Is.EqualTo("Root"));
53
+ Assert.That(Convert.ToInt32(entry["depth"]), Is.EqualTo(0));
54
+ Assert.That(Convert.ToInt32(entry["childCount"]), Is.EqualTo(1));
55
+ Assert.That(entry.ContainsKey("components"), Is.True);
56
+ Assert.That(entry.ContainsKey("layerName"), Is.True);
57
+ Assert.That(entry.ContainsKey("children"), Is.False);
58
+ Assert.That(entry.ContainsKey("position"), Is.False);
59
+ Assert.That(entry.ContainsKey("rotation"), Is.False);
60
+ Assert.That(result.ContainsKey("logs"), Is.False);
61
+ }
62
+
63
+ [Test]
64
+ public void AssetSearch_FiltersActualSubassetTypeMatches()
65
+ {
66
+ var root = ScriptableObject.CreateInstance<SearchRootAsset>();
67
+ root.name = "SmokeRoot";
68
+ AssetDatabase.CreateAsset(root, TempAssetPath);
69
+
70
+ var nested = ScriptableObject.CreateInstance<SearchNestedAsset>();
71
+ nested.name = "SmokeNested";
72
+ AssetDatabase.AddObjectToAsset(nested, root);
73
+ AssetDatabase.ImportAsset(TempAssetPath, ImportAssetOptions.ForceSynchronousImport);
74
+ AssetDatabase.SaveAssets();
75
+
76
+ var response = _router.Dispatch(
77
+ "asset/search",
78
+ 1,
79
+ "{\"type\":\"SearchNestedAsset\",\"name\":\"SmokeNested\",\"path\":\"Assets\",\"maxResults\":10}"
80
+ );
81
+
82
+ Assert.That(response.error, Is.Null);
83
+
84
+ var result = (Dictionary<string, object>)response.result;
85
+ Assert.That(Convert.ToInt32(result["total"]), Is.EqualTo(1));
86
+ Assert.That(Convert.ToInt32(result["returned"]), Is.EqualTo(1));
87
+
88
+ var matches = (List<object>)result["results"];
89
+ var match = (Dictionary<string, object>)matches[0];
90
+ Assert.That(match["path"], Is.EqualTo(TempAssetPath));
91
+ Assert.That(match["type"], Is.EqualTo("SearchNestedAsset"));
92
+ Assert.That(match["name"], Is.EqualTo("SmokeNested"));
93
+ Assert.That(Convert.ToBoolean(match["isSubAsset"]), Is.True);
94
+ }
95
+
96
+ [Test]
97
+ public void LogsTail_TruncatesBulkResultsToTenEntries()
98
+ {
99
+ for (var index = 0; index < 12; index++)
100
+ LogsController.RecordTestLog("info", $"log {index}");
101
+
102
+ var response = _router.Dispatch("logs/tail", 1, "{\"count\":50}");
103
+
104
+ Assert.That(response.error, Is.Null);
105
+
106
+ var result = (Dictionary<string, object>)response.result;
107
+ Assert.That(Convert.ToInt32(result["total"]), Is.EqualTo(12));
108
+ Assert.That(Convert.ToInt32(result["returned"]), Is.EqualTo(10));
109
+ Assert.That(Convert.ToBoolean(result["truncated"]), Is.True);
110
+
111
+ var logs = (List<object>)result["logs"];
112
+ var first = (Dictionary<string, object>)logs[0];
113
+ Assert.That(Convert.ToInt64(first["id"]), Is.EqualTo(12));
114
+ Assert.That(first.ContainsKey("messagePreview"), Is.True);
115
+ }
116
+
117
+ [Test]
118
+ public void LogsSearch_UsesRegexAgainstBufferedHistory()
119
+ {
120
+ LogsController.RecordTestLog("info", "Alpha ready");
121
+ LogsController.RecordTestLog("warning", "Beta failed");
122
+ LogsController.RecordTestLog("error", "Gamma failed hard");
123
+
124
+ var response = _router.Dispatch("logs/search", 1, "{\"pattern\":\"failed\",\"count\":20}");
125
+
126
+ Assert.That(response.error, Is.Null);
127
+
128
+ var result = (Dictionary<string, object>)response.result;
129
+ Assert.That(Convert.ToInt32(result["total"]), Is.EqualTo(2));
130
+
131
+ var logs = (List<object>)result["logs"];
132
+ Assert.That(logs.Count, Is.EqualTo(2));
133
+ var first = (Dictionary<string, object>)logs[0];
134
+ Assert.That(first["level"], Is.EqualTo("error"));
135
+ }
136
+
137
+ [Test]
138
+ public void LogsTail_RespectsLevelThresholdAndIdWindow()
139
+ {
140
+ var first = LogsController.RecordTestLog("info", "Alpha");
141
+ var second = LogsController.RecordTestLog("warning", "Beta warning");
142
+ var third = LogsController.RecordTestLog("error", "Gamma error");
143
+
144
+ var response = _router.Dispatch(
145
+ "logs/tail",
146
+ 1,
147
+ "{\"level\":\"warn\",\"afterId\":" + Convert.ToInt64(first["id"]) + ",\"beforeId\":" + Convert.ToInt64(third["id"]) + ",\"count\":20}"
148
+ );
149
+
150
+ Assert.That(response.error, Is.Null);
151
+
152
+ var result = (Dictionary<string, object>)response.result;
153
+ Assert.That(Convert.ToInt32(result["total"]), Is.EqualTo(1));
154
+
155
+ var logs = (List<object>)result["logs"];
156
+ Assert.That(logs.Count, Is.EqualTo(1));
157
+ var only = (Dictionary<string, object>)logs[0];
158
+ Assert.That(only["level"], Is.EqualTo("warning"));
159
+ Assert.That(Convert.ToInt64(only["id"]), Is.EqualTo(Convert.ToInt64(second["id"])));
160
+ }
161
+
162
+ [Test]
163
+ public void LogsGet_ReturnsFullMessageAndStackTrace()
164
+ {
165
+ var created = LogsController.RecordTestLog("error", "Exploded", "stack line 1\nstack line 2");
166
+ var id = Convert.ToInt64(created["id"]);
167
+
168
+ var response = _router.Dispatch("logs/get", 1, "{\"id\":" + id + "}");
169
+
170
+ Assert.That(response.error, Is.Null);
171
+
172
+ var result = (Dictionary<string, object>)response.result;
173
+ Assert.That(result["message"], Is.EqualTo("Exploded"));
174
+ Assert.That(result["stackTrace"], Is.EqualTo("stack line 1\nstack line 2"));
175
+ }
176
+
177
+ private static void DeleteTempAsset()
178
+ {
179
+ if (AssetDatabase.LoadMainAssetAtPath(TempAssetPath) != null)
180
+ {
181
+ AssetDatabase.DeleteAsset(TempAssetPath);
182
+ AssetDatabase.SaveAssets();
183
+ }
184
+ }
185
+
186
+ private sealed class SearchRootAsset : ScriptableObject
187
+ {
188
+ }
189
+
190
+ private sealed class SearchNestedAsset : ScriptableObject
191
+ {
192
+ }
193
+ }
194
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 600e32c699a40d649ac399a646914084
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "UCP.Bridge.Editor.Tests",
3
+ "references": [
4
+ "UCP.Bridge.Editor"
5
+ ],
6
+ "includePlatforms": [
7
+ "Editor"
8
+ ],
9
+ "optionalUnityReferences": [
10
+ "TestAssemblies"
11
+ ]
12
+ }
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 02e7b7caa7f5b1d4f8b6fe3c2eec4a9a
3
+ AssemblyDefinitionImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 19eb519a09014fb488bba8c69e67b77f
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: fe1724a7076470544ae5120d40748fa1
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "com.ucp.bridge",
3
+ "version": "0.2.3",
4
+ "displayName": "Unity Control Protocol Bridge",
5
+ "description": "WebSocket bridge for programmatic Unity Editor control via CLI and AI agents.",
6
+ "unity": "2021.3",
7
+ "keywords": [
8
+ "automation",
9
+ "devtools",
10
+ "bridge",
11
+ "cli",
12
+ "agent"
13
+ ],
14
+ "author": {
15
+ "name": "UCP Contributors",
16
+ "url": "https://github.com/mflRevan/unity-control-protocol"
17
+ },
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/mflRevan/unity-control-protocol.git"
22
+ },
23
+ "type": "tool",
24
+ "documentationUrl": "https://github.com/mflRevan/unity-control-protocol/blob/main/PROJECT.md",
25
+ "changelogUrl": "https://github.com/mflRevan/unity-control-protocol/blob/main/unity-package/com.ucp.bridge/CHANGELOG.md",
26
+ "dependencies": {}
27
+ }
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: e34242c72ce53964ab5f62878433f5b6
3
+ PackageManifestImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mflrevan/ucp",
3
- "version": "0.2.0",
3
+ "version": "0.2.3",
4
4
  "description": "Unity Control Protocol — CLI for programmatic Unity Editor control",
5
5
  "license": "MIT",
6
6
  "repository": {