windows-development-sandbox 1.25.1 → 1.27.1

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 (211) hide show
  1. package/config.example.json +12 -3
  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/defs.d.ts +198 -3
  5. package/dist/app/features/defs.js +8 -0
  6. package/dist/app/features/settings/categories.def.js +1 -0
  7. package/dist/app/features/unity/index.d.ts +2 -0
  8. package/dist/app/features/unity/index.js +3 -0
  9. package/dist/app/features/unity/unity.def.d.ts +294 -0
  10. package/dist/app/features/unity/unity.def.js +471 -0
  11. package/dist/app/features/unity/unity.run.d.ts +142 -0
  12. package/dist/app/features/unity/unity.run.js +363 -0
  13. package/dist/app/features/unreal/unreal.run.js +13 -3
  14. package/dist/app/registry.js +6 -0
  15. package/dist/bin/agent-sandbox.js +2 -2
  16. package/dist/bin/{chunk-G3TG4ZT7.js → chunk-4TLSWPG7.js} +1 -1
  17. package/dist/bin/{chunk-3GAXLATK.js → chunk-QUHNXHVG.js} +72 -5
  18. package/dist/bin/{chunk-F4PVBN23.js → chunk-RSIX7C6D.js} +3633 -1972
  19. package/dist/bin/claude-host.js +2 -2
  20. package/dist/bin/claude-sbx.js +2 -2
  21. package/dist/bin/codex-sbx.js +2 -2
  22. package/dist/bin/gemini-sbx.js +2 -2
  23. package/dist/bin/sandbox.js +2 -2
  24. package/dist/bin/sbx-hide.js +2 -2
  25. package/dist/bin/sbx-show.js +2 -2
  26. package/dist/cli/commands/launch/launch.js +14 -1
  27. package/dist/cli/commands/registry.js +3 -0
  28. package/dist/cli/manifest.d.ts +33 -1
  29. package/dist/cli/manifest.js +32 -1
  30. package/dist/cli/menu/coverage-exempt.js +1 -0
  31. package/dist/cli/menu/pages/sandbox-page.d.ts +3 -0
  32. package/dist/cli/menu/pages/sandbox-page.js +40 -3
  33. package/dist/cli/menu/views.js +2 -0
  34. package/dist/core/config/defaults.js +16 -3
  35. package/dist/core/schema/accounts.d.ts +3 -0
  36. package/dist/core/schema/accounts.js +1 -0
  37. package/dist/core/schema/config.d.ts +29 -13
  38. package/dist/core/schema/github.d.ts +1 -0
  39. package/dist/core/schema/github.js +3 -0
  40. package/dist/core/schema/pc-installs.d.ts +2 -1
  41. package/dist/core/schema/pc-installs.js +6 -1
  42. package/dist/core/schema/toolchains.d.ts +8 -0
  43. package/dist/core/schema/toolchains.js +19 -4
  44. package/dist/guest/accounts/adapters.js +2 -0
  45. package/dist/guest/accounts/apply.d.ts +4 -2
  46. package/dist/guest/accounts/kinds/perplexityapp.d.ts +7 -0
  47. package/dist/guest/accounts/kinds/perplexityapp.js +53 -0
  48. package/dist/guest/accounts/kinds/unity.d.ts +27 -0
  49. package/dist/guest/accounts/kinds/unity.js +164 -7
  50. package/dist/guest/apps/app-installer.js +18 -0
  51. package/dist/guest/apps/store-app.d.ts +4 -0
  52. package/dist/guest/apps/store-app.js +19 -0
  53. package/dist/guest/apps/store-check.d.ts +8 -0
  54. package/dist/guest/apps/store-check.js +33 -0
  55. package/dist/guest/boot/boot.js +1 -1
  56. package/dist/guest/boot/guide.js +18 -0
  57. package/dist/guest/browser/comet.d.ts +3 -1
  58. package/dist/guest/browser/comet.js +1 -1
  59. package/dist/guest/browser/perplexity-app.d.ts +12 -0
  60. package/dist/guest/browser/perplexity-app.js +60 -0
  61. package/dist/guest/daemon/daemon.js +2 -0
  62. package/dist/guest/devtools/devtool.d.ts +1 -1
  63. package/dist/guest/devtools/registry.js +1 -2
  64. package/dist/guest/entries/tool.js +1 -1
  65. package/dist/guest/setup/addon-mcp.d.ts +7 -2
  66. package/dist/guest/setup/addon-mcp.js +19 -9
  67. package/dist/guest/setup/github-token.js +4 -4
  68. package/dist/guest/setup/unity-agent.d.ts +11 -0
  69. package/dist/guest/setup/unity-agent.js +39 -0
  70. package/dist/guest/toolchains/engines/epic-launcher.d.ts +1 -1
  71. package/dist/guest/toolchains/engines/epic-launcher.js +11 -7
  72. package/dist/guest/toolchains/engines/unity-cli.d.ts +24 -0
  73. package/dist/guest/toolchains/engines/unity-cli.js +74 -0
  74. package/dist/guest/toolchains/engines/unity-hub.d.ts +2 -0
  75. package/dist/guest/toolchains/engines/unity-hub.js +27 -0
  76. package/dist/guest/toolchains/engines/unity-release.d.ts +4 -15
  77. package/dist/guest/toolchains/engines/unity-release.js +17 -5
  78. package/dist/guest/toolchains/engines/unity-status.d.ts +11 -0
  79. package/dist/guest/toolchains/engines/unity-status.js +39 -0
  80. package/dist/guest/toolchains/engines/unity.d.ts +20 -1
  81. package/dist/guest/toolchains/engines/unity.js +250 -3
  82. package/dist/guest/toolchains/engines/unreal-status.js +1 -1
  83. package/dist/guest/toolchains/native/mesa.js +35 -11
  84. package/dist/guest/toolchains/native/unreal.js +1 -0
  85. package/dist/guest/toolchains/plan.js +5 -1
  86. package/dist/guest/toolchains/tools/cli.js +2 -2
  87. package/dist/host/accounts/deliver.d.ts +3 -0
  88. package/dist/host/accounts/deliver.js +23 -0
  89. package/dist/host/accounts/kinds/perplexityapp.d.ts +2 -0
  90. package/dist/host/accounts/kinds/perplexityapp.js +8 -0
  91. package/dist/host/accounts/kinds/unity.d.ts +1 -1
  92. package/dist/host/accounts/kinds/unity.js +60 -8
  93. package/dist/host/accounts/leases.d.ts +2 -1
  94. package/dist/host/accounts/source.d.ts +2 -0
  95. package/dist/host/accounts/source.js +2 -0
  96. package/dist/host/accounts/sources.js +2 -0
  97. package/dist/host/apps/index.d.ts +1 -0
  98. package/dist/host/apps/index.js +2 -0
  99. package/dist/host/apps/store-package.d.ts +51 -0
  100. package/dist/host/apps/store-package.js +209 -0
  101. package/dist/host/github/deliver.d.ts +8 -3
  102. package/dist/host/github/deliver.js +42 -29
  103. package/dist/host/github/index.d.ts +1 -0
  104. package/dist/host/github/index.js +1 -0
  105. package/dist/host/github/pc-login.d.ts +27 -0
  106. package/dist/host/github/pc-login.js +129 -0
  107. package/dist/host/pc-installs/discover.d.ts +4 -0
  108. package/dist/host/pc-installs/discover.js +19 -6
  109. package/dist/host/pc-installs/epic.js +3 -0
  110. package/dist/host/pc-installs/source.d.ts +1 -1
  111. package/dist/host/pc-installs/unity-assets.d.ts +5 -0
  112. package/dist/host/pc-installs/unity-assets.js +18 -0
  113. package/dist/host/pc-installs/unity.d.ts +22 -0
  114. package/dist/host/pc-installs/unity.js +144 -2
  115. package/dist/host/pc-installs/unreal.d.ts +2 -0
  116. package/dist/host/pc-installs/unreal.js +24 -8
  117. package/dist/runtime/agent.js +116 -11
  118. package/dist/runtime/daemon.js +2205 -987
  119. package/dist/runtime/db.js +116 -11
  120. package/dist/runtime/main.js +2578 -1375
  121. package/dist/runtime/netproxy.js +116 -11
  122. package/dist/runtime/tool.js +133 -31
  123. package/dist/runtime/view.js +116 -11
  124. package/dist/selftest/agents-web.test.js +2 -1
  125. package/dist/selftest/engines.test.js +32 -3
  126. package/dist/selftest/github.test.js +64 -1
  127. package/dist/selftest/index.js +10 -0
  128. package/dist/selftest/menu-screens.js +3 -1
  129. package/dist/selftest/mixamo.test.js +1 -1
  130. package/dist/selftest/persisted-installs.test.js +1 -1
  131. package/dist/selftest/service-accounts.test.js +13 -2
  132. package/dist/selftest/store-app.test.d.ts +2 -0
  133. package/dist/selftest/store-app.test.js +162 -0
  134. package/dist/selftest/support/engine-golden.js +7 -0
  135. package/dist/selftest/support/fixtures.d.ts +10 -1
  136. package/dist/selftest/support/unity-sample.d.ts +2 -0
  137. package/dist/selftest/support/unity-sample.js +80 -0
  138. package/dist/selftest/unity-accounts.test.d.ts +2 -0
  139. package/dist/selftest/unity-accounts.test.js +106 -0
  140. package/dist/selftest/unity-agent.test.d.ts +2 -0
  141. package/dist/selftest/unity-agent.test.js +47 -0
  142. package/dist/selftest/unity-page.test.d.ts +2 -0
  143. package/dist/selftest/unity-page.test.js +177 -0
  144. package/dist/selftest/unity-setup.test.d.ts +2 -0
  145. package/dist/selftest/unity-setup.test.js +49 -0
  146. package/dist/selftest/unity.test.js +238 -3
  147. package/dist/shared/accounts/index.d.ts +1 -0
  148. package/dist/shared/accounts/index.js +1 -0
  149. package/dist/shared/accounts/kinds/unity.d.ts +28 -0
  150. package/dist/shared/accounts/kinds/unity.js +88 -0
  151. package/dist/shared/accounts/kinds.d.ts +2 -2
  152. package/dist/shared/accounts/kinds.js +23 -1
  153. package/dist/shared/accounts/payloads.d.ts +52 -0
  154. package/dist/shared/accounts/payloads.js +14 -2
  155. package/dist/shared/apps/catalogue-agents-web.d.ts +7 -0
  156. package/dist/shared/apps/catalogue-agents-web.js +23 -0
  157. package/dist/shared/apps/catalogue-gamedev.d.ts +3 -0
  158. package/dist/shared/apps/catalogue-gamedev.js +31 -0
  159. package/dist/shared/apps/catalogue.d.ts +8 -0
  160. package/dist/shared/apps/index.d.ts +3 -2
  161. package/dist/shared/apps/index.js +3 -2
  162. package/dist/shared/apps/selection.d.ts +6 -0
  163. package/dist/shared/apps/selection.js +9 -0
  164. package/dist/shared/apps/store-package.d.ts +31 -0
  165. package/dist/shared/apps/store-package.js +34 -0
  166. package/dist/shared/channel/schema.d.ts +24 -0
  167. package/dist/shared/channel/secrets.d.ts +17 -0
  168. package/dist/shared/paths/pc-installs.d.ts +1 -1
  169. package/dist/shared/paths/pc-installs.js +1 -0
  170. package/dist/shared/readiness.d.ts +2 -2
  171. package/dist/shared/readiness.js +2 -2
  172. package/dist/shared/unity/asset-cache.d.ts +20 -0
  173. package/dist/shared/unity/asset-cache.js +44 -0
  174. package/dist/shared/unity/cli.d.ts +40 -0
  175. package/dist/shared/unity/cli.js +77 -0
  176. package/dist/shared/unity/editors.d.ts +46 -0
  177. package/dist/shared/unity/editors.js +89 -0
  178. package/dist/shared/unity/guide.d.ts +9 -0
  179. package/dist/shared/unity/guide.js +84 -0
  180. package/dist/shared/unity/index.d.ts +9 -0
  181. package/dist/shared/unity/index.js +11 -0
  182. package/dist/shared/unity/manifest.d.ts +10 -0
  183. package/dist/shared/unity/manifest.js +53 -0
  184. package/dist/shared/unity/mcp.d.ts +8 -0
  185. package/dist/shared/unity/mcp.js +12 -0
  186. package/dist/shared/unity/release.d.ts +28 -0
  187. package/dist/shared/unity/release.js +83 -0
  188. package/dist/shared/unity/status.d.ts +59 -0
  189. package/dist/shared/unity/status.js +45 -0
  190. package/dist/shared/unity/version.d.ts +27 -0
  191. package/dist/shared/unity/version.js +75 -0
  192. package/dist/shared/unreal/status.d.ts +1 -0
  193. package/dist/shared/unreal/status.js +2 -0
  194. package/dist/web/index.html +1 -1
  195. package/dist/web/{main-FNE6XEHA.js → main-VPMYTSUL.js} +67 -67
  196. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  197. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  198. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  199. package/native/scripts/get-store-package.ps1 +58 -0
  200. package/package.json +1 -1
  201. package/sandbox/addons/openupm-cli/package-lock.json +2921 -0
  202. package/sandbox/addons/openupm-cli/package.json +7 -0
  203. package/sandbox/addons/unity-mcp/requirements.in +1 -0
  204. package/sandbox/addons/unity-mcp/requirements.txt +1165 -0
  205. package/sandbox/csharp/AppActivation.cs +38 -0
  206. package/sandbox/scripts/install-store-package.ps1 +28 -0
  207. package/sandbox/scripts/start-store-app.ps1 +29 -0
  208. package/schemas/config.schema.json +61 -6
  209. package/schemas/sandbox-config.schema.json +38 -5
  210. package/dist/guest/devtools/unity.d.ts +0 -2
  211. package/dist/guest/devtools/unity.js +0 -7
@@ -0,0 +1,471 @@
1
+ // Unity: the editors the sandbox has (and which project opens with which), the editors and Asset Store downloads of
2
+ // this PC, the licence and sign-in, the editor bridge of each project, the agent tools and the settings; opening Unity
3
+ // Hub, signing in, adding and removing the editor bridge. Pure: schemas, labels and the view; unity.run.ts reads the
4
+ // sandbox's tools\unity\status.json and looks on this PC.
5
+ import { z } from 'zod';
6
+ import { action, bytesText, defineOperation, defineQuery, defineView, link, } from '../../kernel/index.js';
7
+ import { browseFolder } from '../files/files.def.js';
8
+ const EditorSchema = z.object({
9
+ version: z.string().describe('6000.0.58f2'),
10
+ dir: z.string().describe('Its folder in the sandbox'),
11
+ where: z.string().describe('Where it is, in words'),
12
+ writable: z.boolean().describe('The sandbox can add modules to it'),
13
+ modules: z.array(z.string()).describe('The platform modules it has'),
14
+ sizeBytes: z.number().nullable().describe('Its size, when known'),
15
+ projects: z.array(z.string()).describe('The projects that open with it'),
16
+ });
17
+ const ProjectSchema = z.object({
18
+ project: z.string().describe('The project folder name'),
19
+ folder: z.string().nullable().describe('Its folder on this PC, when it is known'),
20
+ version: z.string().nullable().describe('The editor version its ProjectVersion.txt asks for'),
21
+ editor: z.string().nullable().describe('The editor it opens with'),
22
+ reason: z.string().describe('Why that editor, or why none'),
23
+ bridge: z.enum(['pipeline', 'coplay']).nullable().describe('The editor bridge package it has'),
24
+ pipeline: z.boolean().describe('Its Unity version can take the Unity Pipeline package (Unity 6 and later)'),
25
+ });
26
+ const PackageSchema = z.object({
27
+ publisher: z.string(),
28
+ category: z.string(),
29
+ name: z.string(),
30
+ size: z.string().describe('Its size in words'),
31
+ });
32
+ export const UnityOverviewSchema = z.object({
33
+ setUp: z.boolean().describe('A sandbox has set Unity up (its status file exists)'),
34
+ checkedAt: z.string().nullable().describe('When the sandbox last looked'),
35
+ cli: z.object({ version: z.string(), path: z.string() }).nullable().describe('The Unity CLI the sandbox has'),
36
+ editors: z.array(EditorSchema).describe('The editors the sandbox has'),
37
+ projects: z.array(ProjectSchema).describe('Which editor each project opens with, and its editor bridge'),
38
+ licence: z.object({
39
+ state: z.enum(['active', 'none', 'invalid', 'unknown']),
40
+ kind: z.string(),
41
+ detail: z.string(),
42
+ user: z.string().nullable(),
43
+ }),
44
+ hub: z.object({ installed: z.boolean(), setting: z.boolean() }).describe('Unity Hub in the sandbox'),
45
+ assetCache: z.object({ mode: z.string(), dir: z.string().nullable() }),
46
+ agentTools: z.object({
47
+ cliVersion: z.string().describe('The Unity CLI version the settings ask for'),
48
+ mcp: z.string().nullable().describe('The MCP server name when it was registered'),
49
+ mcpSetting: z.boolean(),
50
+ skills: z.boolean().describe('Unity skills were synced for the agents'),
51
+ skillsSetting: z.boolean(),
52
+ }),
53
+ pc: z.object({
54
+ setting: z.string().describe('pcInstalls.unityEditors'),
55
+ editors: z.array(z.object({ version: z.string(), folder: z.string() })).describe("This PC's editors"),
56
+ problem: z.string().nullable().describe('Why this PC could not be looked at'),
57
+ }),
58
+ assets: z.object({
59
+ setting: z.string().describe('pcInstalls.unityAssets'),
60
+ folders: z.array(z.object({ folder: z.string(), packages: z.array(PackageSchema), more: z.number() })),
61
+ }),
62
+ problem: z.string().nullable().describe('What went wrong in the sandbox, if anything'),
63
+ settings: z.object({
64
+ enabled: z.string(),
65
+ acceptLicense: z.boolean(),
66
+ version: z.string(),
67
+ modules: z.string(),
68
+ hub: z.boolean(),
69
+ keepVersions: z.number(),
70
+ mcp: z.boolean(),
71
+ agentSkills: z.boolean(),
72
+ cliVersion: z.string(),
73
+ assetCache: z.string(),
74
+ }),
75
+ });
76
+ const MessageSchema = z.object({ message: z.string().describe('What happened') });
77
+ export const unityOverview = defineQuery({
78
+ id: 'unity.overview',
79
+ title: 'Unity',
80
+ summary: "the sandbox's editors, this PC's editors and Asset Store downloads, the licence and the editor bridge",
81
+ input: z.object({}),
82
+ output: UnityOverviewSchema,
83
+ cli: { name: 'unity', action: 'status', json: true },
84
+ });
85
+ export const openUnityHub = defineOperation({
86
+ id: 'unity.openHub',
87
+ title: 'Open Unity Hub',
88
+ summary: 'open Unity Hub in the running sandbox (needs the Unity Hub setting on)',
89
+ input: z.object({}),
90
+ output: MessageSchema,
91
+ text: (o) => o.message,
92
+ cli: { name: 'unity', action: 'hub' },
93
+ });
94
+ export const unitySignIn = defineOperation({
95
+ id: 'unity.signIn',
96
+ title: 'Sign in to Unity',
97
+ summary: 'sign in to Unity in the running sandbox (Unity Personal; the licence is kept for the next sandboxes)',
98
+ input: z.object({}),
99
+ output: MessageSchema,
100
+ text: (o) => o.message,
101
+ cli: { name: 'unity', action: 'sign-in' },
102
+ });
103
+ export const addEditorBridge = defineOperation({
104
+ id: 'unity.addBridge',
105
+ title: 'Add the editor bridge…',
106
+ summary: "add the package that lets agents drive a running editor to a project's Packages/manifest.json",
107
+ input: z.object({
108
+ project: z.string().optional().describe('the project folder on this PC (asked when left out)'),
109
+ bridge: z.enum(['pipeline', 'coplay']).optional().describe('pipeline (Unity 6 and later) or coplay (older Unity)'),
110
+ }),
111
+ output: MessageSchema,
112
+ text: (o) => o.message,
113
+ cli: {
114
+ name: 'unity',
115
+ action: 'add-bridge',
116
+ positional: ['project'],
117
+ flags: { bridge: { flag: '--bridge', value: 'name', choices: ['pipeline', 'coplay'] } },
118
+ },
119
+ });
120
+ export const removeEditorBridge = defineOperation({
121
+ id: 'unity.removeBridge',
122
+ title: 'Remove the editor bridge',
123
+ summary: "take the editor bridge package out of a project's Packages/manifest.json",
124
+ input: z.object({
125
+ project: z.string().optional().describe('the project folder on this PC (asked when left out)'),
126
+ }),
127
+ output: MessageSchema,
128
+ text: (o) => o.message,
129
+ cli: { name: 'unity', action: 'remove-bridge', positional: ['project'] },
130
+ });
131
+ const SETTINGS = [
132
+ ['toolchains.unity.enabled', 'Unity set-up'],
133
+ ['toolchains.unity.acceptLicense', 'Licence accepted'],
134
+ ['toolchains.unity.version', 'Editor version'],
135
+ ['toolchains.unity.modules', 'Editor modules'],
136
+ ['toolchains.unity.hub', 'Unity Hub'],
137
+ ['toolchains.unity.keepVersions', 'Editors kept'],
138
+ ['toolchains.unity.mcp', 'MCP server'],
139
+ ['toolchains.unity.agentSkills', 'Agent skills'],
140
+ ['toolchains.unity.cliVersion', 'Unity CLI version'],
141
+ ['toolchains.unity.assetCache', 'Asset Store downloads'],
142
+ ['pcInstalls.unityEditors', "This PC's editors"],
143
+ ['pcInstalls.unityAssets', "This PC's Asset Store downloads"],
144
+ ];
145
+ const yesNo = (b) => (b ? 'yes' : 'no');
146
+ const sizeOf = (bytes) => (bytes === null ? '' : bytesText(bytes));
147
+ function editorsSection(o) {
148
+ const items = o.editors.map((e) => ({
149
+ id: 'editor:' + e.dir,
150
+ label: 'Unity ' + e.version,
151
+ hint: e.where,
152
+ tone: e.writable ? 'ok' : 'accent',
153
+ description: e.dir +
154
+ (e.sizeBytes !== null ? ' (' + sizeOf(e.sizeBytes) + ')' : '') +
155
+ '. ' +
156
+ (e.modules.length ? 'Modules: ' + e.modules.join(', ') + '. ' : 'No platform modules. ') +
157
+ (e.projects.length ? 'Used by ' + e.projects.join(', ') + '.' : 'No project uses it yet.'),
158
+ icon: 'folder',
159
+ cells: {
160
+ version: e.version,
161
+ where: e.where,
162
+ modules: e.modules.join(', ') || '-',
163
+ used: e.projects.join(', ') || '-',
164
+ },
165
+ }));
166
+ return {
167
+ id: 'editors',
168
+ title: 'Editors in the sandbox',
169
+ description: "A project opens with exactly the editor version its ProjectVersion.txt names: this PC's read-only copy first when it has the modules, then the data disk, else it is installed there once the Unity licence is accepted.",
170
+ items,
171
+ columns: [
172
+ { key: 'version', label: 'Version' },
173
+ { key: 'where', label: 'Where' },
174
+ { key: 'modules', label: 'Modules' },
175
+ { key: 'used', label: 'Used by' },
176
+ ],
177
+ columnsOn: 'cli',
178
+ ...(items.length
179
+ ? {}
180
+ : {
181
+ notes: [
182
+ {
183
+ text: o.setUp
184
+ ? 'No editor yet. One of this PC is used as it is; otherwise the next sandbox installs the one a project asks for on the data disk (8-13 GB, kept), once the Unity licence is accepted in the settings below.'
185
+ : 'No sandbox has set Unity up yet. It is set up when a project has ProjectSettings/ProjectVersion.txt (or the Unity set-up setting is on).',
186
+ tone: 'muted',
187
+ },
188
+ ],
189
+ }),
190
+ };
191
+ }
192
+ function pcSection(o) {
193
+ const off = o.pc.setting === 'false';
194
+ return {
195
+ id: 'pc',
196
+ title: 'From this PC',
197
+ description: o.pc.setting === 'auto'
198
+ ? 'The next sandbox set up for Unity maps these read-only and uses them: no download.'
199
+ : "This PC's editors setting is " + o.pc.setting + '.',
200
+ items: o.pc.editors.map((e) => ({
201
+ id: 'pc:' + e.folder,
202
+ label: 'Unity ' + e.version,
203
+ hint: 'read-only',
204
+ description: e.folder + ' appears in the sandbox at C:\\PcInstalls\\unity\\' + e.version + '.',
205
+ cells: { version: e.version, folder: e.folder },
206
+ })),
207
+ columns: [
208
+ { key: 'version', label: 'Version' },
209
+ { key: 'folder', label: 'Folder on this PC' },
210
+ ],
211
+ columnsOn: 'cli',
212
+ notes: o.pc.problem
213
+ ? [{ text: o.pc.problem, tone: 'warn' }]
214
+ : o.pc.editors.length
215
+ ? []
216
+ : [
217
+ {
218
+ text: off
219
+ ? "Turned off (This PC's editors)."
220
+ : 'No Unity editor on this PC yet: one you install with Unity Hub shows up here, and the next sandbox maps it.',
221
+ tone: 'muted',
222
+ },
223
+ ],
224
+ actions: [
225
+ link({ kind: 'setting', key: 'pcInstalls.unityEditors' }, "Change this PC's editors", { verb: 'change' }),
226
+ ],
227
+ };
228
+ }
229
+ const MAX_NOTE = 600;
230
+ function assetsSection(o) {
231
+ const several = o.assets.folders.length > 1;
232
+ const items = o.assets.folders.flatMap((f) => [
233
+ ...f.packages.map((p) => ({
234
+ id: 'asset:' + f.folder + '\\' + p.publisher + '\\' + p.category + '\\' + p.name,
235
+ label: p.name,
236
+ hint: p.size,
237
+ group: p.publisher + (several ? ' (' + f.folder + ')' : ''),
238
+ description: p.category + ' by ' + p.publisher + '. Agents import it into a project with the editor closed.',
239
+ })),
240
+ ...(f.more ? [{ id: 'more:' + f.folder, label: '… and ' + f.more + ' more', tone: 'muted' }] : []),
241
+ ]);
242
+ const empty = !o.assets.folders.some((f) => f.packages.length);
243
+ return {
244
+ id: 'assets',
245
+ title: 'Assets from this PC',
246
+ description: 'The Asset Store packages you downloaded in Unity on this PC. The sandbox sees them read-only at C:\\PcInstalls\\unity\\AssetStore, new ones at once; agents import what a project needs.',
247
+ facts: o.assets.folders.map((f, i) => ({
248
+ id: 'folder:' + i,
249
+ label: 'Download folder',
250
+ value: f.folder,
251
+ description: 'In the sandbox: C:\\PcInstalls\\unity\\AssetStore' + (i ? String(i + 1) : ''),
252
+ })),
253
+ items,
254
+ ...(empty
255
+ ? {
256
+ notes: [
257
+ {
258
+ text: o.assets.setting === 'false'
259
+ ? "Turned off (This PC's Asset Store downloads)."
260
+ : 'No packages yet: the ones you download from the Asset Store in Unity appear here.',
261
+ tone: 'muted',
262
+ },
263
+ ],
264
+ }
265
+ : {}),
266
+ actions: [
267
+ link({ kind: 'setting', key: 'pcInstalls.unityAssets' }, "Change this PC's downloads", { verb: 'change' }),
268
+ ],
269
+ };
270
+ }
271
+ function licenceSection(o) {
272
+ const l = o.licence;
273
+ const text = l.state === 'active'
274
+ ? 'Active'
275
+ : l.state === 'none'
276
+ ? 'No licence'
277
+ : l.state === 'invalid'
278
+ ? 'Refused: sign in again'
279
+ : 'Not checked yet';
280
+ return {
281
+ id: 'licence',
282
+ title: 'Licence and sign-in',
283
+ description: 'Unity Personal is activated by signing in once in a sandbox; the licence is kept for the next ones. A Plus or Pro serial is saved in Accounts and activated in each sandbox.',
284
+ facts: [
285
+ {
286
+ id: 'state',
287
+ label: 'Licence',
288
+ value: text + (l.kind ? ' (' + l.kind + ')' : ''),
289
+ tone: l.state === 'active' ? 'ok' : l.state === 'unknown' ? 'muted' : 'warn',
290
+ ...(l.detail ? { description: l.detail } : {}),
291
+ },
292
+ ...(l.user ? [{ id: 'user', label: 'Signed in as', value: l.user }] : []),
293
+ {
294
+ id: 'hub',
295
+ label: 'Unity Hub',
296
+ value: o.hub.installed ? 'in the sandbox' : o.hub.setting ? 'installed at the next start' : 'off',
297
+ tone: o.hub.installed ? 'ok' : 'muted',
298
+ },
299
+ ],
300
+ actions: [
301
+ action(unitySignIn, {}, { key: 's', verb: 'sign in' }),
302
+ ...(o.hub.installed ? [action(openUnityHub, {}, { key: 'o', verb: 'hub' })] : []),
303
+ link({ kind: 'view', view: 'accounts' }, 'Unity sign-in in Accounts', { verb: 'accounts' }),
304
+ link({ kind: 'setting', key: 'toolchains.unity.hub' }, 'Change Unity Hub', { verb: 'change' }),
305
+ ],
306
+ };
307
+ }
308
+ function projectsSection(o) {
309
+ const items = o.projects.map((p) => {
310
+ const bridge = p.bridge === 'pipeline'
311
+ ? 'Unity Pipeline'
312
+ : p.bridge === 'coplay'
313
+ ? 'MCP for Unity (Coplay)'
314
+ : 'no editor bridge';
315
+ return {
316
+ id: 'project:' + p.project,
317
+ label: p.project,
318
+ hint: p.version ?? 'no Unity version',
319
+ tone: p.editor ? 'ok' : 'warn',
320
+ description: (p.editor ? 'Opens with ' + p.editor + ' (' + p.reason + ')' : p.reason) + '. ' + bridge + '.',
321
+ icon: 'project',
322
+ cells: {
323
+ project: p.project,
324
+ version: p.version ?? '-',
325
+ editor: p.editor ?? '-',
326
+ bridge: p.bridge ?? '-',
327
+ },
328
+ ...(p.folder
329
+ ? {
330
+ actions: [
331
+ p.bridge
332
+ ? action(removeEditorBridge, { project: p.folder }, { key: 'x', verb: 'remove bridge' })
333
+ : action(addEditorBridge, { project: p.folder }, { key: 'a', verb: 'add bridge' }),
334
+ ],
335
+ }
336
+ : {}),
337
+ };
338
+ });
339
+ const notes = items.length
340
+ ? [
341
+ {
342
+ text: 'The editor bridge lets agents drive a running editor (scenes, GameObjects, play mode). Nothing in a project changes unless you add it here.',
343
+ tone: 'muted',
344
+ },
345
+ ]
346
+ : [
347
+ {
348
+ text: o.setUp ? 'No Unity project has been opened in a sandbox yet.' : 'No sandbox has set Unity up yet.',
349
+ tone: 'muted',
350
+ },
351
+ ];
352
+ return {
353
+ id: 'projects',
354
+ title: 'Projects',
355
+ items,
356
+ columns: [
357
+ { key: 'project', label: 'Project' },
358
+ { key: 'version', label: 'Version' },
359
+ { key: 'editor', label: 'Editor' },
360
+ { key: 'bridge', label: 'Bridge' },
361
+ ],
362
+ columnsOn: 'cli',
363
+ notes,
364
+ actions: [action(addEditorBridge, {}, { key: 'b', verb: 'add bridge' })],
365
+ };
366
+ }
367
+ function toolsSection(o) {
368
+ const t = o.agentTools;
369
+ return {
370
+ id: 'tools',
371
+ title: 'Agent tools',
372
+ facts: [
373
+ {
374
+ id: 'cli',
375
+ label: 'Unity CLI',
376
+ value: o.cli ? o.cli.version : 'not set up yet',
377
+ tone: o.cli ? 'ok' : 'muted',
378
+ description: 'The version the settings ask for: ' + t.cliVersion + '. It never updates itself.',
379
+ },
380
+ {
381
+ id: 'mcp',
382
+ label: 'MCP server',
383
+ value: t.mcp ?? (t.mcpSetting ? 'registered at the next start' : 'off'),
384
+ tone: t.mcp ? 'ok' : 'muted',
385
+ description: "In Claude Code and Codex. The open editor's tools need the Unity Pipeline package (Unity 6 and later).",
386
+ },
387
+ {
388
+ id: 'skills',
389
+ label: 'Agent skills',
390
+ value: t.skills ? 'synced' : t.skillsSetting ? 'synced at the next start' : 'off',
391
+ tone: t.skills ? 'ok' : 'muted',
392
+ },
393
+ {
394
+ id: 'cache',
395
+ label: 'Asset Store downloads made in the sandbox',
396
+ value: o.assetCache.mode === 'persisted'
397
+ ? 'kept on the data disk'
398
+ : o.assetCache.mode === 'pc'
399
+ ? "this PC's downloads (read-only)"
400
+ : 'lost when the sandbox closes',
401
+ ...(o.assetCache.dir ? { description: o.assetCache.dir } : {}),
402
+ },
403
+ ],
404
+ actions: [
405
+ link({ kind: 'setting', key: 'toolchains.unity.mcp' }, 'Change the MCP server', { verb: 'change' }),
406
+ link({ kind: 'setting', key: 'toolchains.unity.agentSkills' }, 'Change the agent skills', { verb: 'change' }),
407
+ ],
408
+ };
409
+ }
410
+ function settingsSection(o) {
411
+ const s = o.settings;
412
+ const value = {
413
+ 'toolchains.unity.enabled': s.enabled,
414
+ 'toolchains.unity.acceptLicense': yesNo(s.acceptLicense),
415
+ 'toolchains.unity.version': s.version,
416
+ 'toolchains.unity.modules': s.modules,
417
+ 'toolchains.unity.hub': yesNo(s.hub),
418
+ 'toolchains.unity.keepVersions': String(s.keepVersions),
419
+ 'toolchains.unity.mcp': yesNo(s.mcp),
420
+ 'toolchains.unity.agentSkills': yesNo(s.agentSkills),
421
+ 'toolchains.unity.cliVersion': s.cliVersion,
422
+ 'toolchains.unity.assetCache': s.assetCache,
423
+ 'pcInstalls.unityEditors': o.pc.setting,
424
+ 'pcInstalls.unityAssets': o.assets.setting,
425
+ };
426
+ return {
427
+ id: 'settings',
428
+ title: 'Settings',
429
+ columns: [
430
+ { key: 'setting', label: 'Setting' },
431
+ { key: 'value', label: 'Value' },
432
+ { key: 'key', label: 'Key' },
433
+ ],
434
+ columnsOn: 'cli',
435
+ items: SETTINGS.map(([key, label]) => ({
436
+ id: 'setting:' + key,
437
+ label,
438
+ hint: value[key],
439
+ code: key,
440
+ cells: { setting: label, value: value[key], key },
441
+ ...(key === 'toolchains.unity.acceptLicense' && !s.acceptLicense ? { tone: 'warn' } : {}),
442
+ primary: link({ kind: 'setting', key }, 'Change ' + label.toLowerCase(), { verb: 'change' }),
443
+ })),
444
+ };
445
+ }
446
+ /** The Unity page. */
447
+ export function unityPage(o) {
448
+ return {
449
+ title: 'Unity',
450
+ ...(o.problem ? { notice: { text: o.problem.slice(0, MAX_NOTE), tone: 'danger' } } : {}),
451
+ sections: [
452
+ editorsSection(o),
453
+ pcSection(o),
454
+ assetsSection(o),
455
+ licenceSection(o),
456
+ projectsSection(o),
457
+ toolsSection(o),
458
+ settingsSection(o),
459
+ ],
460
+ };
461
+ }
462
+ export const unityView = defineView({
463
+ id: 'unity',
464
+ title: 'Unity',
465
+ summary: "Editors, this PC's editors and Asset Store downloads, the licence, the editor bridge and Unity Hub.",
466
+ queries: { overview: unityOverview },
467
+ operations: [openUnityHub, unitySignIn, addEditorBridge, removeEditorBridge],
468
+ pickers: [browseFolder],
469
+ inputs: () => ({ overview: {} }),
470
+ build: ({ overview }) => unityPage(overview),
471
+ });
@@ -0,0 +1,142 @@
1
+ import { type Context } from '../../../cli/commands/context.js';
2
+ import { type AssetFs, type Bridge, type UnityStatus } from '../../../shared/unity/index.js';
3
+ import { type UnityOverview } from './unity.def.js';
4
+ export declare function readStatus(dataPath: string): UnityStatus | null;
5
+ /** What this PC has for the next sandbox. */
6
+ export interface PcLook {
7
+ readonly editors: UnityOverview['pc']['editors'];
8
+ readonly assets: UnityOverview['assets']['folders'];
9
+ }
10
+ /** The project folders of this PC known to the tool, by their folder name (for the bridge buttons). */
11
+ export type HostFolders = readonly string[];
12
+ /** The overview from the sandbox's status and this PC's own look (no sandbox needed). */
13
+ export declare function unityOverviewOf(ctx: Context, status: UnityStatus | null, pcLook: () => PcLook, hostFolders?: HostFolders): UnityOverview;
14
+ /** This PC's disk for the packages (bounded lists). */
15
+ export declare const PC_ASSET_FS: AssetFs;
16
+ export declare const unityOverviewRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
17
+ setUp: import("zod").ZodBoolean;
18
+ checkedAt: import("zod").ZodNullable<import("zod").ZodString>;
19
+ cli: import("zod").ZodNullable<import("zod").ZodObject<{
20
+ version: import("zod").ZodString;
21
+ path: import("zod").ZodString;
22
+ }, import("zod/v4/core").$strip>>;
23
+ editors: import("zod").ZodArray<import("zod").ZodObject<{
24
+ version: import("zod").ZodString;
25
+ dir: import("zod").ZodString;
26
+ where: import("zod").ZodString;
27
+ writable: import("zod").ZodBoolean;
28
+ modules: import("zod").ZodArray<import("zod").ZodString>;
29
+ sizeBytes: import("zod").ZodNullable<import("zod").ZodNumber>;
30
+ projects: import("zod").ZodArray<import("zod").ZodString>;
31
+ }, import("zod/v4/core").$strip>>;
32
+ projects: import("zod").ZodArray<import("zod").ZodObject<{
33
+ project: import("zod").ZodString;
34
+ folder: import("zod").ZodNullable<import("zod").ZodString>;
35
+ version: import("zod").ZodNullable<import("zod").ZodString>;
36
+ editor: import("zod").ZodNullable<import("zod").ZodString>;
37
+ reason: import("zod").ZodString;
38
+ bridge: import("zod").ZodNullable<import("zod").ZodEnum<{
39
+ pipeline: "pipeline";
40
+ coplay: "coplay";
41
+ }>>;
42
+ pipeline: import("zod").ZodBoolean;
43
+ }, import("zod/v4/core").$strip>>;
44
+ licence: import("zod").ZodObject<{
45
+ state: import("zod").ZodEnum<{
46
+ unknown: "unknown";
47
+ none: "none";
48
+ active: "active";
49
+ invalid: "invalid";
50
+ }>;
51
+ kind: import("zod").ZodString;
52
+ detail: import("zod").ZodString;
53
+ user: import("zod").ZodNullable<import("zod").ZodString>;
54
+ }, import("zod/v4/core").$strip>;
55
+ hub: import("zod").ZodObject<{
56
+ installed: import("zod").ZodBoolean;
57
+ setting: import("zod").ZodBoolean;
58
+ }, import("zod/v4/core").$strip>;
59
+ assetCache: import("zod").ZodObject<{
60
+ mode: import("zod").ZodString;
61
+ dir: import("zod").ZodNullable<import("zod").ZodString>;
62
+ }, import("zod/v4/core").$strip>;
63
+ agentTools: import("zod").ZodObject<{
64
+ cliVersion: import("zod").ZodString;
65
+ mcp: import("zod").ZodNullable<import("zod").ZodString>;
66
+ mcpSetting: import("zod").ZodBoolean;
67
+ skills: import("zod").ZodBoolean;
68
+ skillsSetting: import("zod").ZodBoolean;
69
+ }, import("zod/v4/core").$strip>;
70
+ pc: import("zod").ZodObject<{
71
+ setting: import("zod").ZodString;
72
+ editors: import("zod").ZodArray<import("zod").ZodObject<{
73
+ version: import("zod").ZodString;
74
+ folder: import("zod").ZodString;
75
+ }, import("zod/v4/core").$strip>>;
76
+ problem: import("zod").ZodNullable<import("zod").ZodString>;
77
+ }, import("zod/v4/core").$strip>;
78
+ assets: import("zod").ZodObject<{
79
+ setting: import("zod").ZodString;
80
+ folders: import("zod").ZodArray<import("zod").ZodObject<{
81
+ folder: import("zod").ZodString;
82
+ packages: import("zod").ZodArray<import("zod").ZodObject<{
83
+ publisher: import("zod").ZodString;
84
+ category: import("zod").ZodString;
85
+ name: import("zod").ZodString;
86
+ size: import("zod").ZodString;
87
+ }, import("zod/v4/core").$strip>>;
88
+ more: import("zod").ZodNumber;
89
+ }, import("zod/v4/core").$strip>>;
90
+ }, import("zod/v4/core").$strip>;
91
+ problem: import("zod").ZodNullable<import("zod").ZodString>;
92
+ settings: import("zod").ZodObject<{
93
+ enabled: import("zod").ZodString;
94
+ acceptLicense: import("zod").ZodBoolean;
95
+ version: import("zod").ZodString;
96
+ modules: import("zod").ZodString;
97
+ hub: import("zod").ZodBoolean;
98
+ keepVersions: import("zod").ZodNumber;
99
+ mcp: import("zod").ZodBoolean;
100
+ agentSkills: import("zod").ZodBoolean;
101
+ cliVersion: import("zod").ZodString;
102
+ assetCache: import("zod").ZodString;
103
+ }, import("zod/v4/core").$strip>;
104
+ }, import("zod/v4/core").$strip>, "unity.overview">, Context>;
105
+ export declare const openUnityHubRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
106
+ message: import("zod").ZodString;
107
+ }, import("zod/v4/core").$strip>, "unity.openHub">, Context>;
108
+ export declare const unitySignInRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
109
+ message: import("zod").ZodString;
110
+ }, import("zod/v4/core").$strip>, "unity.signIn">, Context>;
111
+ /** The newest Unity Pipeline package version, from Unity's package registry (bounded, checked as a version). */
112
+ export declare function latestPipelineVersion(fetcher?: typeof fetch): Promise<string>;
113
+ /** A project of this PC: its manifest file and the editor version it asks for. */
114
+ export declare function unityProjectProblem(dir: string): string | null;
115
+ export interface BridgeEdit {
116
+ readonly file: string;
117
+ readonly message: string;
118
+ }
119
+ export interface BridgeHooks {
120
+ /** The newest Unity Pipeline version (the self-test passes a fixed one: no network). */
121
+ readonly pipelineVersion: () => Promise<string>;
122
+ /** Asks before the file is changed; false leaves it alone. */
123
+ readonly confirm: (file: string, what: string) => Promise<boolean>;
124
+ }
125
+ /** Adds the editor bridge to a project's manifest after the confirmation; the rest of the file is kept. */
126
+ export declare function addBridgeToProject(dir: string, wanted: Bridge | undefined, hooks: BridgeHooks): Promise<BridgeEdit>;
127
+ /** Takes the editor bridge out of a project's manifest after the confirmation. */
128
+ export declare function removeBridgeFromProject(dir: string, hooks: Pick<BridgeHooks, 'confirm'>): Promise<BridgeEdit>;
129
+ export declare const addBridgeRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
130
+ project: import("zod").ZodOptional<import("zod").ZodString>;
131
+ bridge: import("zod").ZodOptional<import("zod").ZodEnum<{
132
+ pipeline: "pipeline";
133
+ coplay: "coplay";
134
+ }>>;
135
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
136
+ message: import("zod").ZodString;
137
+ }, import("zod/v4/core").$strip>, "unity.addBridge">, Context>;
138
+ export declare const removeBridgeRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
139
+ project: import("zod").ZodOptional<import("zod").ZodString>;
140
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
141
+ message: import("zod").ZodString;
142
+ }, import("zod/v4/core").$strip>, "unity.removeBridge">, Context>;