windows-development-sandbox 1.25.0 → 1.27.0

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 (287) hide show
  1. package/config.example.json +17 -5
  2. package/dist/app/features/accounts/services.def.d.ts +1 -1
  3. package/dist/app/features/accounts/services.def.js +1 -1
  4. package/dist/app/features/data/data.def.d.ts +4 -4
  5. package/dist/app/features/data/data.run.d.ts +1 -1
  6. package/dist/app/features/defs.d.ts +356 -6
  7. package/dist/app/features/defs.js +15 -0
  8. package/dist/app/features/projects/projects.def.d.ts +1 -1
  9. package/dist/app/features/projects/projects.run.d.ts +1 -1
  10. package/dist/app/features/settings/categories.def.js +1 -0
  11. package/dist/app/features/unity/index.d.ts +2 -0
  12. package/dist/app/features/unity/index.js +3 -0
  13. package/dist/app/features/unity/unity.def.d.ts +294 -0
  14. package/dist/app/features/unity/unity.def.js +471 -0
  15. package/dist/app/features/unity/unity.run.d.ts +142 -0
  16. package/dist/app/features/unity/unity.run.js +363 -0
  17. package/dist/app/features/unreal/index.d.ts +2 -0
  18. package/dist/app/features/unreal/index.js +3 -0
  19. package/dist/app/features/unreal/unreal.def.d.ts +236 -0
  20. package/dist/app/features/unreal/unreal.def.js +379 -0
  21. package/dist/app/features/unreal/unreal.run.d.ts +96 -0
  22. package/dist/app/features/unreal/unreal.run.js +217 -0
  23. package/dist/app/registry.js +11 -0
  24. package/dist/bin/agent-sandbox.js +2 -2
  25. package/dist/bin/{chunk-IZRGTSQ5.js → chunk-6WWMBCT2.js} +4632 -1941
  26. package/dist/bin/{chunk-SUYYVIDW.js → chunk-JXL6ZOO3.js} +126 -6
  27. package/dist/bin/{chunk-KH4MI2U5.js → chunk-ZXCAVVS4.js} +1 -1
  28. package/dist/bin/claude-host.js +2 -2
  29. package/dist/bin/claude-sbx.js +2 -2
  30. package/dist/bin/codex-sbx.js +2 -2
  31. package/dist/bin/gemini-sbx.js +2 -2
  32. package/dist/bin/sandbox.js +2 -2
  33. package/dist/bin/sbx-hide.js +2 -2
  34. package/dist/bin/sbx-show.js +2 -2
  35. package/dist/cli/commands/launch/launch.js +17 -2
  36. package/dist/cli/commands/registry.js +6 -0
  37. package/dist/cli/manifest.d.ts +51 -1
  38. package/dist/cli/manifest.js +58 -1
  39. package/dist/cli/menu/coverage-exempt.js +2 -0
  40. package/dist/cli/menu/pages/sandbox-page.d.ts +6 -0
  41. package/dist/cli/menu/pages/sandbox-page.js +71 -4
  42. package/dist/cli/menu/views.js +4 -0
  43. package/dist/core/config/defaults.js +33 -6
  44. package/dist/core/schema/accounts.d.ts +3 -0
  45. package/dist/core/schema/accounts.js +1 -0
  46. package/dist/core/schema/config.d.ts +32 -14
  47. package/dist/core/schema/github.d.ts +1 -0
  48. package/dist/core/schema/github.js +3 -0
  49. package/dist/core/schema/pc-installs.d.ts +5 -2
  50. package/dist/core/schema/pc-installs.js +16 -2
  51. package/dist/core/schema/toolchains.d.ts +8 -0
  52. package/dist/core/schema/toolchains.js +20 -5
  53. package/dist/guest/accounts/adapters.js +2 -0
  54. package/dist/guest/accounts/apply.d.ts +4 -2
  55. package/dist/guest/accounts/kinds/epic.js +18 -13
  56. package/dist/guest/accounts/kinds/perplexityapp.d.ts +7 -0
  57. package/dist/guest/accounts/kinds/perplexityapp.js +53 -0
  58. package/dist/guest/accounts/kinds/unity.d.ts +27 -0
  59. package/dist/guest/accounts/kinds/unity.js +164 -7
  60. package/dist/guest/apps/after-install.d.ts +1 -1
  61. package/dist/guest/apps/after-install.js +6 -1
  62. package/dist/guest/apps/app-installer.d.ts +1 -0
  63. package/dist/guest/apps/app-installer.js +31 -3
  64. package/dist/guest/apps/comet-unpack.js +3 -2
  65. package/dist/guest/apps/resolvers-gamedev.js +55 -1
  66. package/dist/guest/apps/store-app.d.ts +4 -0
  67. package/dist/guest/apps/store-app.js +19 -0
  68. package/dist/guest/apps/store-check.d.ts +8 -0
  69. package/dist/guest/apps/store-check.js +33 -0
  70. package/dist/guest/boot/boot.js +15 -2
  71. package/dist/guest/boot/guide.js +42 -0
  72. package/dist/guest/browser/comet.d.ts +3 -1
  73. package/dist/guest/browser/comet.js +1 -1
  74. package/dist/guest/browser/perplexity-app.d.ts +12 -0
  75. package/dist/guest/browser/perplexity-app.js +60 -0
  76. package/dist/guest/daemon/daemon.js +5 -0
  77. package/dist/guest/devtools/devtool.d.ts +1 -1
  78. package/dist/guest/devtools/registry.js +1 -2
  79. package/dist/guest/entries/tool.js +1 -1
  80. package/dist/guest/setup/addon-mcp.d.ts +12 -0
  81. package/dist/guest/setup/addon-mcp.js +29 -4
  82. package/dist/guest/setup/browser-gpu.js +14 -11
  83. package/dist/guest/setup/github-token.js +4 -4
  84. package/dist/guest/setup/headroom.js +4 -0
  85. package/dist/guest/setup/unity-agent.d.ts +11 -0
  86. package/dist/guest/setup/unity-agent.js +36 -0
  87. package/dist/guest/toolchains/engines/epic-launcher.d.ts +26 -0
  88. package/dist/guest/toolchains/engines/epic-launcher.js +127 -0
  89. package/dist/guest/toolchains/engines/unity-cli.d.ts +24 -0
  90. package/dist/guest/toolchains/engines/unity-cli.js +74 -0
  91. package/dist/guest/toolchains/engines/unity-hub.d.ts +2 -0
  92. package/dist/guest/toolchains/engines/unity-hub.js +27 -0
  93. package/dist/guest/toolchains/engines/unity-release.d.ts +4 -15
  94. package/dist/guest/toolchains/engines/unity-release.js +17 -5
  95. package/dist/guest/toolchains/engines/unity-status.d.ts +11 -0
  96. package/dist/guest/toolchains/engines/unity-status.js +39 -0
  97. package/dist/guest/toolchains/engines/unity.d.ts +20 -1
  98. package/dist/guest/toolchains/engines/unity.js +250 -3
  99. package/dist/guest/toolchains/engines/unreal-engines.d.ts +21 -1
  100. package/dist/guest/toolchains/engines/unreal-engines.js +163 -3
  101. package/dist/guest/toolchains/engines/unreal-status.d.ts +13 -0
  102. package/dist/guest/toolchains/engines/unreal-status.js +41 -0
  103. package/dist/guest/toolchains/native/debuggers.d.ts +6 -0
  104. package/dist/guest/toolchains/native/debuggers.js +57 -0
  105. package/dist/guest/toolchains/native/mesa.js +15 -8
  106. package/dist/guest/toolchains/native/rust-extras.d.ts +7 -0
  107. package/dist/guest/toolchains/native/rust-extras.js +23 -1
  108. package/dist/guest/toolchains/native/unreal.d.ts +2 -2
  109. package/dist/guest/toolchains/native/unreal.js +96 -18
  110. package/dist/guest/toolchains/plan.js +17 -2
  111. package/dist/guest/toolchains/tools/cli.js +2 -2
  112. package/dist/guest/toolchains/tools/vscode-profile.js +2 -0
  113. package/dist/host/accounts/deliver.js +4 -0
  114. package/dist/host/accounts/kinds/epic.js +11 -5
  115. package/dist/host/accounts/kinds/perplexityapp.d.ts +2 -0
  116. package/dist/host/accounts/kinds/perplexityapp.js +8 -0
  117. package/dist/host/accounts/kinds/unity.d.ts +1 -1
  118. package/dist/host/accounts/kinds/unity.js +60 -8
  119. package/dist/host/accounts/leases.d.ts +2 -1
  120. package/dist/host/accounts/source.d.ts +2 -0
  121. package/dist/host/accounts/source.js +1 -0
  122. package/dist/host/accounts/sources.js +2 -0
  123. package/dist/host/apps/index.d.ts +1 -0
  124. package/dist/host/apps/index.js +2 -0
  125. package/dist/host/apps/store-package.d.ts +51 -0
  126. package/dist/host/apps/store-package.js +209 -0
  127. package/dist/host/github/deliver.d.ts +8 -3
  128. package/dist/host/github/deliver.js +42 -29
  129. package/dist/host/github/index.d.ts +1 -0
  130. package/dist/host/github/index.js +1 -0
  131. package/dist/host/github/pc-login.d.ts +27 -0
  132. package/dist/host/github/pc-login.js +129 -0
  133. package/dist/host/pc-installs/discover.d.ts +6 -0
  134. package/dist/host/pc-installs/discover.js +37 -5
  135. package/dist/host/pc-installs/epic.d.ts +3 -0
  136. package/dist/host/pc-installs/epic.js +33 -2
  137. package/dist/host/pc-installs/source.d.ts +1 -1
  138. package/dist/host/pc-installs/unity-assets.d.ts +5 -0
  139. package/dist/host/pc-installs/unity-assets.js +18 -0
  140. package/dist/host/pc-installs/unity.d.ts +20 -0
  141. package/dist/host/pc-installs/unity.js +135 -2
  142. package/dist/host/pc-installs/unreal-vault.d.ts +11 -0
  143. package/dist/host/pc-installs/unreal-vault.js +78 -0
  144. package/dist/host/pc-installs/unreal.d.ts +36 -0
  145. package/dist/host/pc-installs/unreal.js +145 -2
  146. package/dist/host/profile/claude-profile.d.ts +8 -0
  147. package/dist/host/profile/claude-profile.js +43 -4
  148. package/dist/host/profile/index.d.ts +1 -1
  149. package/dist/host/profile/index.js +1 -1
  150. package/dist/runtime/agent.js +197 -18
  151. package/dist/runtime/daemon.js +3938 -1386
  152. package/dist/runtime/db.js +197 -18
  153. package/dist/runtime/main.js +4336 -1978
  154. package/dist/runtime/netproxy.js +197 -18
  155. package/dist/runtime/tool.js +214 -38
  156. package/dist/runtime/view.js +197 -18
  157. package/dist/selftest/agent-paths.test.js +1 -0
  158. package/dist/selftest/agents-web.test.js +14 -1
  159. package/dist/selftest/engines.test.js +602 -3
  160. package/dist/selftest/github.test.js +64 -1
  161. package/dist/selftest/heavy-load.test.js +3 -1
  162. package/dist/selftest/hostile-input.test.js +11 -1
  163. package/dist/selftest/index.js +12 -0
  164. package/dist/selftest/menu-screens.js +5 -1
  165. package/dist/selftest/mixamo.test.d.ts +2 -0
  166. package/dist/selftest/mixamo.test.js +60 -0
  167. package/dist/selftest/persisted-installs.test.js +1 -1
  168. package/dist/selftest/secrets.test.js +36 -1
  169. package/dist/selftest/service-accounts.test.js +1 -1
  170. package/dist/selftest/store-app.test.d.ts +2 -0
  171. package/dist/selftest/store-app.test.js +162 -0
  172. package/dist/selftest/support/engine-golden.js +10 -0
  173. package/dist/selftest/support/fixtures.d.ts +13 -2
  174. package/dist/selftest/support/unity-sample.d.ts +2 -0
  175. package/dist/selftest/support/unity-sample.js +80 -0
  176. package/dist/selftest/support/unreal-sample.d.ts +2 -0
  177. package/dist/selftest/support/unreal-sample.js +83 -0
  178. package/dist/selftest/toolchains.test.js +32 -2
  179. package/dist/selftest/unity-accounts.test.d.ts +2 -0
  180. package/dist/selftest/unity-accounts.test.js +106 -0
  181. package/dist/selftest/unity-agent.test.d.ts +2 -0
  182. package/dist/selftest/unity-agent.test.js +47 -0
  183. package/dist/selftest/unity-page.test.d.ts +2 -0
  184. package/dist/selftest/unity-page.test.js +177 -0
  185. package/dist/selftest/unity-setup.test.d.ts +2 -0
  186. package/dist/selftest/unity-setup.test.js +49 -0
  187. package/dist/selftest/unity.test.js +238 -3
  188. package/dist/shared/accounts/index.d.ts +2 -1
  189. package/dist/shared/accounts/index.js +2 -1
  190. package/dist/shared/accounts/kinds/epic.d.ts +6 -1
  191. package/dist/shared/accounts/kinds/epic.js +11 -1
  192. package/dist/shared/accounts/kinds/unity.d.ts +28 -0
  193. package/dist/shared/accounts/kinds/unity.js +88 -0
  194. package/dist/shared/accounts/kinds.d.ts +2 -2
  195. package/dist/shared/accounts/kinds.js +23 -1
  196. package/dist/shared/accounts/payloads.d.ts +52 -0
  197. package/dist/shared/accounts/payloads.js +14 -2
  198. package/dist/shared/apps/associations.d.ts +7 -0
  199. package/dist/shared/apps/associations.js +26 -0
  200. package/dist/shared/apps/catalogue-agents-web.d.ts +11 -1
  201. package/dist/shared/apps/catalogue-agents-web.js +28 -2
  202. package/dist/shared/apps/catalogue-gamedev.d.ts +3 -0
  203. package/dist/shared/apps/catalogue-gamedev.js +102 -1
  204. package/dist/shared/apps/catalogue.d.ts +8 -0
  205. package/dist/shared/apps/index.d.ts +5 -2
  206. package/dist/shared/apps/index.js +5 -2
  207. package/dist/shared/apps/preview.d.ts +2 -0
  208. package/dist/shared/apps/preview.js +10 -0
  209. package/dist/shared/apps/selection.d.ts +6 -0
  210. package/dist/shared/apps/selection.js +9 -0
  211. package/dist/shared/apps/store-package.d.ts +31 -0
  212. package/dist/shared/apps/store-package.js +34 -0
  213. package/dist/shared/browser-policy.d.ts +14 -0
  214. package/dist/shared/browser-policy.js +22 -0
  215. package/dist/shared/channel/schema.d.ts +24 -0
  216. package/dist/shared/channel/secrets.d.ts +17 -0
  217. package/dist/shared/io/index.d.ts +1 -0
  218. package/dist/shared/io/index.js +1 -0
  219. package/dist/shared/io/rotate-log.d.ts +2 -0
  220. package/dist/shared/io/rotate-log.js +16 -0
  221. package/dist/shared/memory/policy.d.ts +5 -0
  222. package/dist/shared/memory/policy.js +7 -0
  223. package/dist/shared/paths/pc-installs.d.ts +13 -2
  224. package/dist/shared/paths/pc-installs.js +2 -0
  225. package/dist/shared/readiness.d.ts +2 -3
  226. package/dist/shared/readiness.js +2 -3
  227. package/dist/shared/signer.d.ts +4 -0
  228. package/dist/shared/signer.js +2 -0
  229. package/dist/shared/unity/asset-cache.d.ts +20 -0
  230. package/dist/shared/unity/asset-cache.js +44 -0
  231. package/dist/shared/unity/cli.d.ts +40 -0
  232. package/dist/shared/unity/cli.js +77 -0
  233. package/dist/shared/unity/editors.d.ts +46 -0
  234. package/dist/shared/unity/editors.js +89 -0
  235. package/dist/shared/unity/guide.d.ts +9 -0
  236. package/dist/shared/unity/guide.js +84 -0
  237. package/dist/shared/unity/index.d.ts +9 -0
  238. package/dist/shared/unity/index.js +11 -0
  239. package/dist/shared/unity/manifest.d.ts +10 -0
  240. package/dist/shared/unity/manifest.js +53 -0
  241. package/dist/shared/unity/mcp.d.ts +8 -0
  242. package/dist/shared/unity/mcp.js +12 -0
  243. package/dist/shared/unity/release.d.ts +28 -0
  244. package/dist/shared/unity/release.js +83 -0
  245. package/dist/shared/unity/status.d.ts +59 -0
  246. package/dist/shared/unity/status.js +45 -0
  247. package/dist/shared/unity/version.d.ts +27 -0
  248. package/dist/shared/unity/version.js +75 -0
  249. package/dist/shared/unreal/engines.d.ts +161 -0
  250. package/dist/shared/unreal/engines.js +308 -0
  251. package/dist/shared/unreal/guide.d.ts +19 -0
  252. package/dist/shared/unreal/guide.js +105 -0
  253. package/dist/shared/unreal/index.d.ts +7 -0
  254. package/dist/shared/unreal/index.js +8 -0
  255. package/dist/shared/unreal/launcher-files.d.ts +88 -0
  256. package/dist/shared/unreal/launcher-files.js +292 -0
  257. package/dist/shared/unreal/mixamo.d.ts +5 -0
  258. package/dist/shared/unreal/mixamo.js +16 -0
  259. package/dist/shared/unreal/room.d.ts +17 -0
  260. package/dist/shared/unreal/room.js +34 -0
  261. package/dist/shared/unreal/status.d.ts +54 -0
  262. package/dist/shared/unreal/status.js +57 -0
  263. package/dist/shared/unreal/vault.d.ts +21 -0
  264. package/dist/shared/unreal/vault.js +67 -0
  265. package/dist/shared/unreal/vs-check.d.ts +39 -0
  266. package/dist/shared/unreal/vs-check.js +79 -0
  267. package/dist/web/index.html +1 -1
  268. package/dist/web/{main-CCILLX2M.js → main-VPMYTSUL.js} +87 -87
  269. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  270. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  271. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  272. package/native/scripts/get-store-package.ps1 +58 -0
  273. package/package.json +1 -1
  274. package/sandbox/addons/openupm-cli/package-lock.json +2921 -0
  275. package/sandbox/addons/openupm-cli/package.json +7 -0
  276. package/sandbox/addons/unity-mcp/requirements.in +1 -0
  277. package/sandbox/addons/unity-mcp/requirements.txt +1165 -0
  278. package/sandbox/csharp/AppActivation.cs +38 -0
  279. package/sandbox/csharp/VsSetup.cs +210 -0
  280. package/sandbox/scripts/get-vs-setup.ps1 +93 -0
  281. package/sandbox/scripts/install-store-package.ps1 +28 -0
  282. package/sandbox/scripts/set-registry-values.ps1 +35 -0
  283. package/sandbox/scripts/start-store-app.ps1 +29 -0
  284. package/schemas/config.schema.json +96 -8
  285. package/schemas/sandbox-config.schema.json +46 -6
  286. package/dist/guest/devtools/unity.d.ts +0 -2
  287. package/dist/guest/devtools/unity.js +0 -7
@@ -2,10 +2,9 @@
2
2
  // entries here (the end of round 2 leaves it empty). Pure.
3
3
  export const NOT_READY = {
4
4
  /** Toolchains whose step is a stub: their settings rows are hidden and "auto" never turns them on. */
5
- toolchains: ['unity', 'godot', 'android', 'flutter', 'dart', 'reactNative'],
5
+ toolchains: ['godot', 'android', 'flutter', 'dart', 'reactNative'],
6
6
  /** Service sign-ins whose host or guest side is a stub: the menu and the web do not list them. */
7
- kinds: ['unity', 'keystore', 'play', 'expo', 'appstore'],
8
- unreal: ['engines'],
7
+ kinds: ['keystore', 'play', 'expo', 'appstore'],
9
8
  };
10
9
  export const isToolchainReady = (name) => !NOT_READY.toolchains.includes(name);
11
10
  export const isKindReady = (kind) => !NOT_READY.kinds.includes(kind);
@@ -21,4 +21,8 @@ export declare const SIGNERS: {
21
21
  readonly unity: {
22
22
  readonly subject: readonly ["^CN=\"?Unity Technologies"];
23
23
  };
24
+ /** The Epic Games Launcher's MSI (checked on EpicInstaller-20.3.3.msi). */
25
+ readonly epic: {
26
+ readonly subject: readonly ["^CN=Epic Games Inc\\., O=Epic Games Inc\\., L=Cary, S=North Carolina, C=US"];
27
+ };
24
28
  };
@@ -12,4 +12,6 @@ export const SIGNERS = {
12
12
  microsoft: { subject: ['^CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US$'] },
13
13
  valve: { subject: ['^CN="?Valve(,| Corp)'] },
14
14
  unity: { subject: ['^CN="?Unity Technologies'] },
15
+ /** The Epic Games Launcher's MSI (checked on EpicInstaller-20.3.3.msi). */
16
+ epic: { subject: ['^CN=Epic Games Inc\\., O=Epic Games Inc\\., L=Cary, S=North Carolina, C=US'] },
15
17
  };
@@ -0,0 +1,20 @@
1
+ export declare function assetStoreDir(root: string): string;
2
+ /** The cache roots of this PC that hold an Asset Store-5.x folder: the environment's first, then %APPDATA%\Unity. */
3
+ export declare function pcAssetCacheDirs(pc: {
4
+ readonly appData: string;
5
+ readonly envValue?: string | undefined;
6
+ }, isDir: (dir: string) => boolean): string[];
7
+ export interface AssetFs {
8
+ list(dir: string): string[];
9
+ isDir(dir: string): boolean;
10
+ /** A file's size, or null when it is a folder or missing. */
11
+ size(file: string): number | null;
12
+ }
13
+ export interface AssetPackage {
14
+ readonly publisher: string;
15
+ readonly category: string;
16
+ readonly name: string;
17
+ readonly sizeBytes: number;
18
+ }
19
+ /** The .unitypackage files in an Asset Store-5.x folder (three levels deep), sorted, at most 2000. */
20
+ export declare function assetPackages(dir: string, fs: AssetFs): AssetPackage[];
@@ -0,0 +1,44 @@
1
+ // The Unity Asset Store's download cache: <root>\Asset Store-5.x\<publisher>\<category>\<name>.unitypackage. The root
2
+ // is ASSETSTORE_CACHE_PATH, else %APPDATA%\Unity. Pure apart from the reads it is given; every walk is bounded.
3
+ import path from 'node:path';
4
+ const win = path.win32;
5
+ const MAX_PACKAGES = 2000;
6
+ const MAX_ROOTS = 2;
7
+ export function assetStoreDir(root) {
8
+ return root + '\\Asset Store-5.x';
9
+ }
10
+ /** The cache roots of this PC that hold an Asset Store-5.x folder: the environment's first, then %APPDATA%\Unity. */
11
+ export function pcAssetCacheDirs(pc, isDir) {
12
+ const all = [pc.envValue?.trim() ?? '', pc.appData ? win.join(pc.appData, 'Unity') : ''].filter(Boolean);
13
+ return all
14
+ .map((d) => win.normalize(d).replace(/\\+$/, ''))
15
+ .filter((d, i, a) => a.findIndex((o) => o.toLowerCase() === d.toLowerCase()) === i)
16
+ .filter((d) => isDir(assetStoreDir(d)))
17
+ .slice(0, MAX_ROOTS);
18
+ }
19
+ /** The .unitypackage files in an Asset Store-5.x folder (three levels deep), sorted, at most 2000. */
20
+ export function assetPackages(dir, fs) {
21
+ const found = [];
22
+ const sorted = (d) => fs.list(d).sort((a, b) => a.localeCompare(b));
23
+ for (const publisher of sorted(dir)) {
24
+ const pdir = win.join(dir, publisher);
25
+ if (!fs.isDir(pdir))
26
+ continue;
27
+ for (const category of sorted(pdir)) {
28
+ const cdir = win.join(pdir, category);
29
+ if (!fs.isDir(cdir))
30
+ continue;
31
+ for (const file of sorted(cdir)) {
32
+ if (!/\.unitypackage$/i.test(file))
33
+ continue;
34
+ const size = fs.size(win.join(cdir, file));
35
+ if (size === null)
36
+ continue;
37
+ found.push({ publisher, category, name: file.replace(/\.unitypackage$/i, ''), sizeBytes: size });
38
+ if (found.length >= MAX_PACKAGES)
39
+ return found;
40
+ }
41
+ }
42
+ }
43
+ return found;
44
+ }
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ export declare const UNITY_CLI_CDN = "https://public-cdn.cloud.unity3d.com/hub/prod/cli";
3
+ export declare const DEFAULT_UNITY_CLI = "1.0.0-beta.16";
4
+ /** The manifest of a CLI version: "latest" is the newest beta, else that version's own latest.json. */
5
+ export declare function cliManifestUrl(version: string): string;
6
+ export declare const CliManifestSchema: z.ZodObject<{
7
+ version: z.ZodString;
8
+ binaries: z.ZodRecord<z.ZodString, z.ZodObject<{
9
+ filename: z.ZodString;
10
+ sha256: z.ZodString;
11
+ size: z.ZodOptional<z.ZodNumber>;
12
+ }, z.core.$strip>>;
13
+ }, z.core.$strip>;
14
+ export type CliManifest = z.infer<typeof CliManifestSchema>;
15
+ export interface CliBinary {
16
+ readonly version: string;
17
+ readonly url: string;
18
+ readonly sha256: string;
19
+ readonly size: number;
20
+ }
21
+ /** The Windows build for this CPU, or null when the manifest has none or its file name or hash is unexpected. */
22
+ export declare function pickCliBinary(m: CliManifest, arch: 'x64' | 'arm64'): CliBinary | null;
23
+ /** No telemetry, hints, pager, elevation prompt or first-run set-up (the skills are synced by us when asked). */
24
+ export declare const UNITY_CLI_ENV: {
25
+ readonly UNITY_NO_CLI_INVOKED_TELEMETRY: "1";
26
+ readonly UNITY_NO_AGENT_HINTS: "1";
27
+ readonly UNITY_CLI_SKIP_SETUP: "1";
28
+ readonly UNITY_NO_PAGER: "1";
29
+ readonly UNITY_NO_ELEVATE: "1";
30
+ };
31
+ /** `unity install <version> -c <changeset> -m <ids> --cm`. --download-directory is not in the docs: from the plan. */
32
+ export declare function installArgs(version: string, changeset: string | null, modules: readonly string[], dir: string): string[];
33
+ /** `unity install-modules -e <version> -m <ids> --cm`. --download-directory is not in the docs: from the plan. */
34
+ export declare function installModulesArgs(version: string, modules: readonly string[], dir: string): string[];
35
+ /** Where the CLI installs editors. `--set` is not in the docs (they say "run install-path --help"): from the plan. */
36
+ export declare function installPathArgs(dir: string): string[];
37
+ /** `unity editors add <path...>` registers editors installed outside the Hub (the docs pass their folders). */
38
+ export declare function editorsAddArgs(exes: readonly string[]): string[];
39
+ /** `unity license status` is not in the docs; --format json is the global output option. */
40
+ export declare function licenceStatusArgs(): string[];
@@ -0,0 +1,77 @@
1
+ // The Unity CLI (`unity`): where its pinned build is published, how a download is checked, the environment it runs in
2
+ // and the argument lists we pass it. The flags below are checked against the docs
3
+ // (docs.unity.com/en-us/unity-cli/reference), not a live run; the ones the docs do not settle are marked.
4
+ import { z } from 'zod';
5
+ export const UNITY_CLI_CDN = 'https://public-cdn.cloud.unity3d.com/hub/prod/cli';
6
+ export const DEFAULT_UNITY_CLI = '1.0.0-beta.16';
7
+ const CLI_VERSION = /^\d+\.\d+\.\d+(-[A-Za-z0-9.]+)?$/;
8
+ const CLI_FILE = /^unity-windows-(x64|arm64)\.exe$/;
9
+ const SHA256 = /^[0-9a-f]{64}$/i;
10
+ /** The manifest of a CLI version: "latest" is the newest beta, else that version's own latest.json. */
11
+ export function cliManifestUrl(version) {
12
+ if (version === 'latest')
13
+ return UNITY_CLI_CDN + '/latest-beta.json';
14
+ if (!CLI_VERSION.test(version))
15
+ throw new Error('not a Unity CLI version: ' + version);
16
+ return UNITY_CLI_CDN + '/' + version + '/latest.json';
17
+ }
18
+ export const CliManifestSchema = z.object({
19
+ version: z.string().regex(CLI_VERSION),
20
+ binaries: z
21
+ .record(z.string().max(40), z.object({
22
+ filename: z.string().max(80),
23
+ sha256: z.string().max(80),
24
+ size: z.number().int().min(0).optional(),
25
+ }))
26
+ .refine((r) => Object.keys(r).length <= 20),
27
+ });
28
+ /** The Windows build for this CPU, or null when the manifest has none or its file name or hash is unexpected. */
29
+ export function pickCliBinary(m, arch) {
30
+ const b = m.binaries['win32-' + arch];
31
+ if (!b)
32
+ return null;
33
+ const file = CLI_FILE.exec(b.filename);
34
+ if (!file || file[1] !== arch || !SHA256.test(b.sha256))
35
+ return null;
36
+ return {
37
+ version: m.version,
38
+ url: UNITY_CLI_CDN + '/' + m.version + '/' + b.filename,
39
+ sha256: b.sha256.toLowerCase(),
40
+ size: b.size ?? 0,
41
+ };
42
+ }
43
+ /** No telemetry, hints, pager, elevation prompt or first-run set-up (the skills are synced by us when asked). */
44
+ export const UNITY_CLI_ENV = {
45
+ UNITY_NO_CLI_INVOKED_TELEMETRY: '1',
46
+ UNITY_NO_AGENT_HINTS: '1',
47
+ UNITY_CLI_SKIP_SETUP: '1',
48
+ UNITY_NO_PAGER: '1',
49
+ UNITY_NO_ELEVATE: '1',
50
+ };
51
+ /** `unity install <version> -c <changeset> -m <ids> --cm`. --download-directory is not in the docs: from the plan. */
52
+ export function installArgs(version, changeset, modules, dir) {
53
+ return [
54
+ 'install',
55
+ version,
56
+ ...(changeset ? ['-c', changeset] : []),
57
+ ...(modules.length ? ['-m', ...modules, '--cm'] : []),
58
+ '--download-directory',
59
+ dir,
60
+ ];
61
+ }
62
+ /** `unity install-modules -e <version> -m <ids> --cm`. --download-directory is not in the docs: from the plan. */
63
+ export function installModulesArgs(version, modules, dir) {
64
+ return ['install-modules', '-e', version, '-m', ...modules, '--cm', '--download-directory', dir];
65
+ }
66
+ /** Where the CLI installs editors. `--set` is not in the docs (they say "run install-path --help"): from the plan. */
67
+ export function installPathArgs(dir) {
68
+ return ['install-path', '--set', dir];
69
+ }
70
+ /** `unity editors add <path...>` registers editors installed outside the Hub (the docs pass their folders). */
71
+ export function editorsAddArgs(exes) {
72
+ return ['editors', 'add', ...exes];
73
+ }
74
+ /** `unity license status` is not in the docs; --format json is the global output option. */
75
+ export function licenceStatusArgs() {
76
+ return ['license', 'status', '--format', 'json'];
77
+ }
@@ -0,0 +1,46 @@
1
+ export interface UnityFs {
2
+ exists(file: string): boolean;
3
+ list(dir: string): string[];
4
+ }
5
+ export interface UnityEditor {
6
+ readonly version: string;
7
+ /** The folder that holds Editor\Unity.exe. */
8
+ readonly root: string;
9
+ readonly exe: string;
10
+ readonly origin: 'pc' | 'data';
11
+ readonly writable: boolean;
12
+ /** Module ids found installed (android, webgl, ios, windows-il2cpp). */
13
+ readonly modules: readonly string[];
14
+ }
15
+ export declare const ORIGIN_LABELS: {
16
+ readonly pc: "this PC, read-only";
17
+ readonly data: "the data disk, kept between sandboxes";
18
+ };
19
+ /** The modules installed in an editor folder. */
20
+ export declare function editorModules(root: string, fs: UnityFs): string[];
21
+ export interface EditorSearch {
22
+ /** This PC's editors as mapped read-only (id = the version). */
23
+ readonly mapped: readonly {
24
+ readonly guest: string;
25
+ readonly id: string;
26
+ }[];
27
+ /** tools\unity\editors on the data disk. */
28
+ readonly dataRoot: string;
29
+ }
30
+ export declare function findEditors(search: EditorSearch, fs: UnityFs): UnityEditor[];
31
+ export interface WantedEditor {
32
+ readonly version: string;
33
+ readonly changeset: string | null;
34
+ }
35
+ export interface EditorChoice {
36
+ readonly editor: UnityEditor | null;
37
+ /** What to install on the data disk, when nothing usable is there. */
38
+ readonly install: WantedEditor | null;
39
+ readonly reason: string;
40
+ }
41
+ /**
42
+ * The editor for a project: exactly the version it asks for. This PC's (read-only) when it has every module, then the
43
+ * data disk's, else install it when the licence is accepted. A PC editor that lacks modules is still used when nothing
44
+ * can be installed.
45
+ */
46
+ export declare function chooseEditor(editors: readonly UnityEditor[], wanted: WantedEditor | null, modules: readonly string[], canInstall: boolean): EditorChoice;
@@ -0,0 +1,89 @@
1
+ // The Unity editors a sandbox has (this PC's, read-only, and the data disk's) and which one a project opens with. An
2
+ // editor is never swapped for another version: opening a project in another Unity upgrades its files. Pure apart from
3
+ // the file reads it is given.
4
+ import path from 'node:path';
5
+ import { UNITY_VERSION } from './version.js';
6
+ const win = path.win32;
7
+ export const ORIGIN_LABELS = {
8
+ pc: 'this PC, read-only',
9
+ data: 'the data disk, kept between sandboxes',
10
+ };
11
+ /** Folders under Editor\Data\PlaybackEngines that show a module is installed (windows-il2cpp: verify on an editor). */
12
+ const MODULE_FOLDERS = {
13
+ android: ['AndroidPlayer'],
14
+ webgl: ['WebGLSupport'],
15
+ ios: ['iOSSupport'],
16
+ 'windows-il2cpp': [
17
+ 'windowsstandalonesupport\\Variations\\win64_player_development_il2cpp',
18
+ 'windowsstandalonesupport\\Variations\\win64_development_il2cpp',
19
+ ],
20
+ };
21
+ /** The modules installed in an editor folder. */
22
+ export function editorModules(root, fs) {
23
+ const engines = win.join(root, 'Editor', 'Data', 'PlaybackEngines');
24
+ return Object.entries(MODULE_FOLDERS)
25
+ .filter(([, folders]) => folders.some((f) => fs.exists(win.join(engines, f))))
26
+ .map(([id]) => id);
27
+ }
28
+ /** A data editor counts once its install finished: .complete.json (ours) or a Hub/CLI modules.json. */
29
+ function isComplete(root, fs) {
30
+ return fs.exists(win.join(root, '.complete.json')) || fs.exists(win.join(root, 'modules.json'));
31
+ }
32
+ export function findEditors(search, fs) {
33
+ const found = [];
34
+ for (const m of search.mapped) {
35
+ const exe = win.join(m.guest, 'Editor', 'Unity.exe');
36
+ if (UNITY_VERSION.test(m.id) && fs.exists(exe))
37
+ found.push({
38
+ version: m.id,
39
+ root: m.guest,
40
+ exe,
41
+ origin: 'pc',
42
+ writable: false,
43
+ modules: editorModules(m.guest, fs),
44
+ });
45
+ }
46
+ for (const name of fs.list(search.dataRoot)) {
47
+ if (name.startsWith('.staging-') || !UNITY_VERSION.test(name))
48
+ continue;
49
+ const root = win.join(search.dataRoot, name);
50
+ const exe = win.join(root, 'Editor', 'Unity.exe');
51
+ if (isComplete(root, fs) && fs.exists(exe))
52
+ found.push({ version: name, root, exe, origin: 'data', writable: true, modules: editorModules(root, fs) });
53
+ }
54
+ return found;
55
+ }
56
+ /**
57
+ * The editor for a project: exactly the version it asks for. This PC's (read-only) when it has every module, then the
58
+ * data disk's, else install it when the licence is accepted. A PC editor that lacks modules is still used when nothing
59
+ * can be installed.
60
+ */
61
+ export function chooseEditor(editors, wanted, modules, canInstall) {
62
+ if (!wanted)
63
+ return { editor: null, install: null, reason: 'no ProjectSettings/ProjectVersion.txt' };
64
+ const v = wanted.version;
65
+ const same = editors.filter((e) => e.version === v);
66
+ const pc = same.find((e) => e.origin === 'pc');
67
+ const data = same.find((e) => e.origin === 'data');
68
+ const missing = (e) => modules.find((m) => !e?.modules.includes(m));
69
+ const asks = 'the project asks for ' + v;
70
+ if (pc && missing(pc) === undefined)
71
+ return { editor: pc, install: null, reason: asks };
72
+ if (data) {
73
+ const lack = pc ? missing(pc) : undefined;
74
+ return {
75
+ editor: data,
76
+ install: null,
77
+ reason: lack === undefined ? asks : v + ' from this PC lacks ' + lack + '; using the data disk copy',
78
+ };
79
+ }
80
+ if (canInstall)
81
+ return { editor: null, install: wanted, reason: v + ' is not here yet; installing it on the data disk' };
82
+ if (pc)
83
+ return { editor: pc, install: null, reason: asks };
84
+ return {
85
+ editor: null,
86
+ install: null,
87
+ reason: v + ' is not on this PC or the data disk; accept the Unity licence (Unity set-up settings) to install it',
88
+ };
89
+ }
@@ -0,0 +1,9 @@
1
+ import type { UnityStatus } from './status.js';
2
+ export interface UnityGuideProject {
3
+ /** The project's folder in the sandbox. */
4
+ readonly workspace: string;
5
+ }
6
+ /** The guide's Unity lines for these projects (none when Unity is not set up). */
7
+ export declare function unityGuideLines(status: UnityStatus, projects: readonly UnityGuideProject[]): string[];
8
+ /** One line about a project's editor, for the status the agent and the page show. */
9
+ export declare function unitySummaryLine(status: UnityStatus, workspace: string): string;
@@ -0,0 +1,84 @@
1
+ // The Unity lines of the sandbox guide (the managed CLAUDE.md and AGENTS.md): which editor each project opens with and
2
+ // the plain commands an agent builds, tests and imports with. Pure, from the status the sandbox wrote (status.ts).
3
+ import path from 'node:path';
4
+ import { ORIGIN_LABELS } from './editors.js';
5
+ const win = path.win32;
6
+ function sameDir(a, b) {
7
+ return a.toLowerCase() === b.toLowerCase();
8
+ }
9
+ function exeOf(root) {
10
+ return win.join(root, 'Editor', 'Unity.exe');
11
+ }
12
+ /** The guide's Unity lines for these projects (none when Unity is not set up). */
13
+ export function unityGuideLines(status, projects) {
14
+ const lines = [];
15
+ const several = projects.length > 1;
16
+ let first = null;
17
+ const bridges = new Set();
18
+ let withoutBridge = false;
19
+ for (const p of projects) {
20
+ const choice = status.projects.find((s) => sameDir(s.workspace, p.workspace));
21
+ const editor = choice?.editor ? status.editors.find((e) => sameDir(e.root, choice.editor)) : undefined;
22
+ if (!choice || !editor)
23
+ continue;
24
+ const exe = exeOf(editor.root);
25
+ const name = several ? ' (' + win.basename(p.workspace) + ')' : '';
26
+ first ??= { exe, workspace: p.workspace };
27
+ lines.push('- Unity' +
28
+ name +
29
+ ': editor ' +
30
+ editor.version +
31
+ ' at `' +
32
+ exe +
33
+ '` (' +
34
+ ORIGIN_LABELS[editor.origin] +
35
+ '; ' +
36
+ choice.reason +
37
+ '). Build or run code without opening it: `"' +
38
+ exe +
39
+ '" -batchmode -nographics -quit -projectPath "' +
40
+ p.workspace +
41
+ '" -executeMethod <Class.Method> -logFile -`; tests: `-runTests -testPlatform EditMode -testResults <file>` (without -quit). Opening the project in another Unity version upgrades its files: never do that without asking the user.' +
42
+ (editor.writable ? '' : " It is the user's PC copy, read-only: never add modules to it."));
43
+ if (choice.bridge)
44
+ bridges.add(choice.bridge);
45
+ else
46
+ withoutBridge = true;
47
+ }
48
+ if (!lines.length)
49
+ return lines;
50
+ if (status.cli)
51
+ lines.push('- `unity` (Unity CLI ' +
52
+ status.cli.version +
53
+ ') is on PATH: `unity editors -i`, `unity build`, `unity test`, `unity open <project>` (opens it signed in).');
54
+ if (bridges.has('pipeline'))
55
+ lines.push('- The open editor can be driven with `unity command` and `unity eval` (Unity Pipeline package); MCP clients use sbx-unity.');
56
+ if (bridges.has('coplay'))
57
+ lines.push('- The open editor can be driven with MCP for Unity (sbx-unity-mcp in Apps).');
58
+ if (withoutBridge)
59
+ lines.push("- To drive a running editor (scenes, GameObjects, play mode) the project needs an editor bridge package: ask the user to add it on the sandbox tool's Unity page. Never change Packages/manifest.json yourself unless asked.");
60
+ if (status.pcAssets.length && first)
61
+ lines.push("- The user's Unity Asset Store downloads (read-only): `" +
62
+ status.pcAssets[0] +
63
+ '`; import one with the editor closed: `"' +
64
+ first.exe +
65
+ '" -batchmode -nographics -quit -projectPath "' +
66
+ first.workspace +
67
+ '" -importPackage "<file>"`.' +
68
+ (status.assetCache.dir ? ' Downloads made here go to `' + status.assetCache.dir + '` (kept).' : ''));
69
+ if (status.licence.state !== 'active')
70
+ lines.push('- Unity licence: ' +
71
+ status.licence.detail +
72
+ ". Batch mode fails without one: ask the user to sign in to Unity on the sandbox tool's Unity page.");
73
+ return lines;
74
+ }
75
+ /** One line about a project's editor, for the status the agent and the page show. */
76
+ export function unitySummaryLine(status, workspace) {
77
+ const choice = status.projects.find((s) => sameDir(s.workspace, workspace));
78
+ if (!choice)
79
+ return 'Unity: not set up for this project';
80
+ const editor = choice.editor ? status.editors.find((e) => sameDir(e.root, choice.editor)) : undefined;
81
+ return editor
82
+ ? 'Unity ' + editor.version + ' (' + ORIGIN_LABELS[editor.origin] + '; ' + choice.reason + ')'
83
+ : 'Unity: no editor (' + choice.reason + ')';
84
+ }
@@ -0,0 +1,9 @@
1
+ export * from './version.js';
2
+ export * from './editors.js';
3
+ export * from './release.js';
4
+ export * from './cli.js';
5
+ export * from './mcp.js';
6
+ export * from './manifest.js';
7
+ export * from './asset-cache.js';
8
+ export * from './status.js';
9
+ export * from './guide.js';
@@ -0,0 +1,11 @@
1
+ // Unity editors, the release API, the Unity CLI, the editor bridge and the Unity status, shared by the sandbox and this
2
+ // PC (pure).
3
+ export * from './version.js';
4
+ export * from './editors.js';
5
+ export * from './release.js';
6
+ export * from './cli.js';
7
+ export * from './mcp.js';
8
+ export * from './manifest.js';
9
+ export * from './asset-cache.js';
10
+ export * from './status.js';
11
+ export * from './guide.js';
@@ -0,0 +1,10 @@
1
+ export declare const PIPELINE_PACKAGE = "com.unity.pipeline";
2
+ export declare const COPLAY_PACKAGE = "com.coplaydev.unity-mcp";
3
+ export declare const COPLAY_PACKAGE_URL = "https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v10.3.0";
4
+ /** The Pipeline version added when none is given (0.10 is the one the plan was written against). */
5
+ export declare const DEFAULT_PIPELINE_VERSION = "0.10.0";
6
+ export type Bridge = 'pipeline' | 'coplay';
7
+ /** Which bridge the project has, or null (also for a file that is not a manifest). */
8
+ export declare function bridgeOf(text: string): Bridge | null;
9
+ /** The manifest with the bridge added or removed: key order, 2-space indent, trailing newline and CRLF kept. */
10
+ export declare function withBridge(text: string, bridge: Bridge, on: boolean, pipelineVersion?: string): string;
@@ -0,0 +1,53 @@
1
+ // Packages/manifest.json and the editor bridge: the package that lets `unity command` / `unity eval` (Unity Pipeline,
2
+ // Unity 6 and later) or MCP for Unity (Coplay) drive a running editor. Edited only when the user asks. Pure text.
3
+ export const PIPELINE_PACKAGE = 'com.unity.pipeline';
4
+ export const COPLAY_PACKAGE = 'com.coplaydev.unity-mcp';
5
+ export const COPLAY_PACKAGE_URL = 'https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#v10.3.0';
6
+ /** The Pipeline version added when none is given (0.10 is the one the plan was written against). */
7
+ export const DEFAULT_PIPELINE_VERSION = '0.10.0';
8
+ const MAX_MANIFEST_BYTES = 1024 * 1024;
9
+ const SEMVER = /^\d{1,6}\.\d{1,6}\.\d{1,6}(-[0-9A-Za-z.-]{1,50})?(\+[0-9A-Za-z.-]{1,50})?$/;
10
+ function parseManifest(text) {
11
+ if (Buffer.byteLength(text) > MAX_MANIFEST_BYTES)
12
+ throw new Error('Packages/manifest.json is over 1 MB');
13
+ const json = JSON.parse(text.replace(/^\uFEFF/, ''));
14
+ if (typeof json !== 'object' || json === null || Array.isArray(json))
15
+ throw new Error('Packages/manifest.json is not an object');
16
+ const m = json;
17
+ if (m.dependencies !== undefined &&
18
+ (typeof m.dependencies !== 'object' || m.dependencies === null || Array.isArray(m.dependencies)))
19
+ throw new Error('Packages/manifest.json: dependencies is not an object');
20
+ return m;
21
+ }
22
+ /** Which bridge the project has, or null (also for a file that is not a manifest). */
23
+ export function bridgeOf(text) {
24
+ try {
25
+ const deps = parseManifest(text).dependencies ?? {};
26
+ if (PIPELINE_PACKAGE in deps)
27
+ return 'pipeline';
28
+ if (COPLAY_PACKAGE in deps)
29
+ return 'coplay';
30
+ return null;
31
+ }
32
+ catch {
33
+ // Not JSON or not a manifest: no bridge to report.
34
+ return null;
35
+ }
36
+ }
37
+ /** The manifest with the bridge added or removed: key order, 2-space indent, trailing newline and CRLF kept. */
38
+ export function withBridge(text, bridge, on, pipelineVersion) {
39
+ const m = parseManifest(text);
40
+ const name = bridge === 'pipeline' ? PIPELINE_PACKAGE : COPLAY_PACKAGE;
41
+ if (on) {
42
+ const version = pipelineVersion ?? DEFAULT_PIPELINE_VERSION;
43
+ if (bridge === 'pipeline' && !SEMVER.test(version))
44
+ throw new Error('not a package version: ' + version);
45
+ const deps = (m.dependencies ??= {});
46
+ deps[name] = bridge === 'pipeline' ? version : COPLAY_PACKAGE_URL;
47
+ }
48
+ else if (m.dependencies) {
49
+ delete m.dependencies[name];
50
+ }
51
+ const out = JSON.stringify(m, null, 2) + '\n';
52
+ return text.includes('\r\n') ? out.replace(/\n/g, '\r\n') : out;
53
+ }
@@ -0,0 +1,8 @@
1
+ export declare const UNITY_MCP_NAME = "sbx-unity";
2
+ export interface UnityMcpServer {
3
+ readonly type: 'stdio';
4
+ readonly command: string;
5
+ readonly args: readonly string[];
6
+ readonly env: Readonly<Record<string, string>>;
7
+ }
8
+ export declare function unityCliMcpServer(unityExe: string, projectPath: string | null): UnityMcpServer;
@@ -0,0 +1,12 @@
1
+ // The Unity CLI as an MCP server (`unity mcp --cli-tools`, stdio) for Claude Code and Codex. Read-only tools always;
2
+ // the open editor's tools when the project has the Unity Pipeline package.
3
+ import { UNITY_CLI_ENV } from './cli.js';
4
+ export const UNITY_MCP_NAME = 'sbx-unity';
5
+ export function unityCliMcpServer(unityExe, projectPath) {
6
+ return {
7
+ type: 'stdio',
8
+ command: unityExe,
9
+ args: ['mcp', '--cli-tools'],
10
+ env: { ...UNITY_CLI_ENV, ...(projectPath ? { UNITY_PROJECT_PATH: projectPath } : {}) },
11
+ };
12
+ }
@@ -0,0 +1,28 @@
1
+ /** The request for one editor version (Windows, x86_64, one result). */
2
+ export declare function releaseUrl(version: string): string;
3
+ export interface UnityRelease {
4
+ readonly version: string;
5
+ readonly changeset: string;
6
+ readonly editor: {
7
+ readonly url: string;
8
+ /** As Unity writes it: "md5-<base64>". */
9
+ readonly integrity: string | null;
10
+ readonly downloadBytes: number;
11
+ readonly installedBytes: number;
12
+ };
13
+ readonly modules: readonly {
14
+ readonly id: string;
15
+ readonly downloadBytes: number;
16
+ readonly installedBytes: number;
17
+ readonly integrity: string | null;
18
+ /** The ids of its sub-modules (android: the SDK, NDK and OpenJDK parts). */
19
+ readonly children: readonly string[];
20
+ /** The sub-modules' sizes together. */
21
+ readonly childDownloadBytes: number;
22
+ readonly childInstalledBytes: number;
23
+ }[];
24
+ }
25
+ /** The first release an API answer holds (the EXE installer), or null when it holds none or has another shape. */
26
+ export declare function pickRelease(json: unknown): UnityRelease | null;
27
+ /** Room an install needs: (editor download + installed + the chosen modules with their children) plus 10%. */
28
+ export declare function installNeedBytes(r: UnityRelease, modules: readonly string[]): number;