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
@@ -0,0 +1,5 @@
1
+ import type { PcInstall } from '../../shared/paths/index.js';
2
+ import type { PcInstallSource } from './source.js';
3
+ /** The Asset Store folders as installs to map. */
4
+ export declare function unityAssetInstalls(dirs: readonly string[]): PcInstall[];
5
+ export declare const unityAssets: PcInstallSource;
@@ -0,0 +1,18 @@
1
+ import { assetCacheEnv, unityAssetCacheDirs, unityPcFiles } from './unity.js';
2
+ /** The Asset Store folders as installs to map. */
3
+ export function unityAssetInstalls(dirs) {
4
+ return dirs.map((dir, i) => ({
5
+ kind: 'unity-assets',
6
+ id: i ? 'AssetStore' + (i + 1) : 'AssetStore',
7
+ name: 'Unity Asset Store downloads' + (i ? ' ' + (i + 1) : ''),
8
+ host: dir,
9
+ guest: '',
10
+ }));
11
+ }
12
+ export const unityAssets = {
13
+ kind: 'unity-assets',
14
+ setting: 'unityAssets',
15
+ find(_wanted, pc) {
16
+ return unityAssetInstalls(unityAssetCacheDirs(unityPcFiles(pc), assetCacheEnv(pc)));
17
+ },
18
+ };
@@ -1,2 +1,22 @@
1
+ import type { PcInstall } from '../../shared/paths/index.js';
2
+ import type { PcEnv } from '../accounts/index.js';
1
3
  import type { PcInstallSource } from './source.js';
4
+ /** At most this many editors of this PC are mapped. */
5
+ export declare const MAX_PC_EDITORS = 12;
6
+ /** The files and folders of this PC the search reads (the self-test passes its own). */
7
+ export interface UnityPcFiles {
8
+ read(file: string, max: number): Buffer | null;
9
+ isDir(dir: string): boolean;
10
+ list(dir: string): string[];
11
+ readonly appData: string;
12
+ readonly programFiles: string;
13
+ }
14
+ /** The editors of this PC: all of them (true) or the listed versions. Each version once, each folder once. */
15
+ export declare function findUnityEditorsOnPc(files: UnityPcFiles, wanted: true | readonly string[]): PcInstall[];
16
+ /** The Asset Store-5.x folders of this PC (the environment's cache root first, then %APPDATA%\Unity), to map. */
17
+ export declare function unityAssetCacheDirs(files: UnityPcFiles, envValue: string | undefined): string[];
18
+ /** This PC's disk for the search. */
19
+ export declare function unityPcFiles(pc: PcEnv): UnityPcFiles;
20
+ /** The cache root the environment names: this terminal's variable, else the saved user one. */
21
+ export declare function assetCacheEnv(pc: PcEnv): string | undefined;
2
22
  export declare const unityInstalls: PcInstallSource;
@@ -1,7 +1,140 @@
1
+ // Unity editors of this PC (pcInstalls.unityEditors): Unity Hub's default folder (<Program Files>\Unity\Hub\Editor),
2
+ // the folder named by %APPDATA%\UnityHub\secondaryInstallPath.json and the editors in editors-v2.json. An editor counts
3
+ // only with Editor\Unity.exe; its folder is mapped read-only at C:\PcInstalls\unity\<version>. Every file is read
4
+ // bounded and every name is checked: what Hub wrote is data, never trusted.
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { z } from 'zod';
8
+ import { readBoundedFile } from '../../shared/io/index.js';
9
+ import { assetStoreDir, pcAssetCacheDirs, UNITY_VERSION } from '../../shared/unity/index.js';
10
+ const win = path.win32;
11
+ /** At most this many editors of this PC are mapped. */
12
+ export const MAX_PC_EDITORS = 12;
13
+ const MAX_SECONDARY_BYTES = 4 * 1024;
14
+ const MAX_EDITORS_FILE_BYTES = 1024 * 1024;
15
+ const MAX_EDITOR_ENTRIES = 200;
16
+ const MAX_LISTED = 500;
17
+ const EditorsFileSchema = z.union([
18
+ z.array(z.unknown()).max(MAX_EDITOR_ENTRIES),
19
+ z.object({ data: z.array(z.unknown()).max(MAX_EDITOR_ENTRIES) }).passthrough(),
20
+ ]);
21
+ const EditorEntrySchema = z
22
+ .object({
23
+ version: z.string().max(40),
24
+ location: z.union([z.string().max(1000), z.array(z.string().max(1000)).max(8)]),
25
+ })
26
+ .passthrough();
27
+ function jsonOf(files, file, max) {
28
+ const bytes = files.read(file, max);
29
+ if (!bytes)
30
+ return null;
31
+ try {
32
+ return JSON.parse(bytes.toString('utf8').replace(/^\uFEFF/, ''));
33
+ }
34
+ catch {
35
+ return null; // Not JSON: Hub's file is ignored.
36
+ }
37
+ }
38
+ /** The folder in secondaryInstallPath.json (a JSON string, absolute only), or null. */
39
+ function secondaryRoot(files) {
40
+ const json = jsonOf(files, win.join(files.appData, 'UnityHub', 'secondaryInstallPath.json'), MAX_SECONDARY_BYTES);
41
+ return typeof json === 'string' && json.length < 1000 && win.isAbsolute(json) ? win.normalize(json) : null;
42
+ }
43
+ const hasEditorExe = (root, files) => files.list(win.join(root, 'Editor')).some((n) => n.toLowerCase() === 'unity.exe');
44
+ /** The editors editors-v2.json lists: only `...\Editor\Unity.exe`, the root two levels up. */
45
+ function listedEditors(files) {
46
+ const parsed = EditorsFileSchema.safeParse(jsonOf(files, win.join(files.appData, 'UnityHub', 'editors-v2.json'), MAX_EDITORS_FILE_BYTES));
47
+ if (!parsed.success)
48
+ return [];
49
+ const entries = Array.isArray(parsed.data) ? parsed.data : parsed.data.data;
50
+ const out = [];
51
+ for (const raw of entries) {
52
+ const e = EditorEntrySchema.safeParse(raw);
53
+ if (!e.success)
54
+ continue;
55
+ for (const location of [e.data.location].flat()) {
56
+ const exe = win.normalize(location);
57
+ if (!win.isAbsolute(exe) || win.basename(exe).toLowerCase() !== 'unity.exe')
58
+ continue;
59
+ const editorDir = win.dirname(exe);
60
+ if (win.basename(editorDir).toLowerCase() !== 'editor')
61
+ continue;
62
+ out.push({ version: e.data.version, root: win.dirname(editorDir) });
63
+ }
64
+ }
65
+ return out;
66
+ }
67
+ /** The editors of this PC: all of them (true) or the listed versions. Each version once, each folder once. */
68
+ export function findUnityEditorsOnPc(files, wanted) {
69
+ const candidates = [];
70
+ const hubFolders = [win.join(files.programFiles, 'Unity', 'Hub', 'Editor'), secondaryRoot(files)].filter((d) => d !== null);
71
+ for (const folder of hubFolders)
72
+ for (const name of files.list(folder).slice(0, MAX_LISTED).sort())
73
+ if (UNITY_VERSION.test(name))
74
+ candidates.push({ version: name, root: win.join(folder, name) });
75
+ candidates.push(...listedEditors(files));
76
+ const found = [];
77
+ for (const c of candidates) {
78
+ if (found.length >= MAX_PC_EDITORS)
79
+ break;
80
+ if (!UNITY_VERSION.test(c.version))
81
+ continue;
82
+ if (wanted !== true && !wanted.includes(c.version))
83
+ continue;
84
+ const key = c.root.toLowerCase();
85
+ if (found.some((f) => f.id === c.version || f.host.toLowerCase() === key))
86
+ continue;
87
+ if (!files.isDir(c.root) || !hasEditorExe(c.root, files))
88
+ continue;
89
+ found.push({
90
+ kind: 'unity',
91
+ id: c.version,
92
+ name: 'Unity ' + c.version,
93
+ version: c.version,
94
+ host: c.root,
95
+ guest: '',
96
+ });
97
+ }
98
+ return found;
99
+ }
100
+ /** The Asset Store-5.x folders of this PC (the environment's cache root first, then %APPDATA%\Unity), to map. */
101
+ export function unityAssetCacheDirs(files, envValue) {
102
+ return pcAssetCacheDirs({ appData: files.appData, envValue }, files.isDir).map(assetStoreDir);
103
+ }
104
+ function listDir(dir) {
105
+ try {
106
+ return fs.readdirSync(dir).slice(0, MAX_LISTED);
107
+ }
108
+ catch {
109
+ return []; // Not a folder: nothing in it.
110
+ }
111
+ }
112
+ function isDir(dir) {
113
+ try {
114
+ return fs.statSync(dir).isDirectory();
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ }
120
+ /** This PC's disk for the search. */
121
+ export function unityPcFiles(pc) {
122
+ return {
123
+ read: readBoundedFile,
124
+ isDir,
125
+ list: listDir,
126
+ appData: pc.appData,
127
+ programFiles: pc.programFiles ?? 'C:\\Program Files',
128
+ };
129
+ }
130
+ /** The cache root the environment names: this terminal's variable, else the saved user one. */
131
+ export function assetCacheEnv(pc) {
132
+ return pc.env?.ASSETSTORE_CACHE_PATH ?? pc.userVariable?.('ASSETSTORE_CACHE_PATH') ?? undefined;
133
+ }
1
134
  export const unityInstalls = {
2
135
  kind: 'unity',
3
136
  setting: 'unityEditors',
4
- find(_wanted, _pc) {
5
- return [];
137
+ find(wanted, pc) {
138
+ return findUnityEditorsOnPc(unityPcFiles(pc), wanted === true ? true : wanted.map(String));
6
139
  },
7
140
  };
@@ -0,0 +1,11 @@
1
+ import type { PcInstall } from '../../shared/paths/index.js';
2
+ import { type VaultFs } from '../../shared/unreal/index.js';
3
+ import type { PcEnv } from '../accounts/index.js';
4
+ import type { PcInstallSource } from './source.js';
5
+ /** The vault cache folders of this PC: the ones its launcher settings name, else the default. */
6
+ export declare function vaultDirs(pc: Pick<PcEnv, 'localAppData' | 'programData'>, isDir: (dir: string) => boolean): string[];
7
+ /** The vault folders as installs to map (read-only). */
8
+ export declare function vaultInstalls(dirs: readonly string[]): PcInstall[];
9
+ /** This PC's disk for vaultPacks (bounded lists). */
10
+ export declare const PC_VAULT_FS: VaultFs;
11
+ export declare const unrealVault: PcInstallSource;
@@ -0,0 +1,78 @@
1
+ // The Epic Games Launcher's vault cache of this PC (pcInstalls.unrealAssets): the Fab and Marketplace packs you
2
+ // downloaded, mapped read-only at C:\PcInstalls\unreal\Vault (Vault2 ... for more folders), so what you download on the
3
+ // PC is in the sandbox at once. Its folders come from the launcher's settings (shared/unreal/vault.ts), else the
4
+ // default one; only folders that exist are mapped.
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { epicSettingsFiles, MAX_EPIC_INI_BYTES } from '../../shared/accounts/index.js';
8
+ import { decodeText, readBoundedFile } from '../../shared/io/index.js';
9
+ import { defaultVaultDir, vaultDirsFromIni } from '../../shared/unreal/index.js';
10
+ const MAX_VAULTS = 4;
11
+ /** The vault cache folders of this PC: the ones its launcher settings name, else the default. */
12
+ export function vaultDirs(pc, isDir) {
13
+ const named = pc.localAppData
14
+ ? epicSettingsFiles(pc.localAppData).flatMap((file) => {
15
+ const bytes = readBoundedFile(file, MAX_EPIC_INI_BYTES);
16
+ return bytes ? vaultDirsFromIni(decodeText(bytes).text) : [];
17
+ })
18
+ : [];
19
+ const all = [...named, defaultVaultDir(pc.programData)];
20
+ return all
21
+ .filter((d, i) => all.findIndex((o) => o.toLowerCase() === d.toLowerCase()) === i)
22
+ .filter(isDir)
23
+ .slice(0, MAX_VAULTS);
24
+ }
25
+ /** The vault folders as installs to map (read-only). */
26
+ export function vaultInstalls(dirs) {
27
+ return dirs.map((dir, i) => ({
28
+ kind: 'unreal-vault',
29
+ id: i ? 'Vault' + (i + 1) : 'Vault',
30
+ name: 'Epic Games Launcher vault cache' + (i ? ' ' + (i + 1) : ''),
31
+ host: dir,
32
+ guest: '',
33
+ }));
34
+ }
35
+ const isDir = (dir) => {
36
+ try {
37
+ return fs.statSync(dir).isDirectory();
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ };
43
+ /** This PC's disk for vaultPacks (bounded lists). */
44
+ export const PC_VAULT_FS = {
45
+ exists: (file) => fs.existsSync(file),
46
+ list: (dir) => {
47
+ try {
48
+ return fs.readdirSync(dir).slice(0, 5000);
49
+ }
50
+ catch {
51
+ return []; // Not a folder: nothing in it.
52
+ }
53
+ },
54
+ size: (file) => {
55
+ try {
56
+ const s = fs.lstatSync(file);
57
+ return s.isFile() ? s.size : null;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ },
63
+ isDir: (dir) => {
64
+ try {
65
+ return fs.lstatSync(dir).isDirectory();
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ },
71
+ };
72
+ export const unrealVault = {
73
+ kind: 'unreal-vault',
74
+ setting: 'unrealAssets',
75
+ find(_wanted, pc) {
76
+ return vaultInstalls(vaultDirs(pc, isDir)).map((v) => ({ ...v, host: path.win32.normalize(v.host) }));
77
+ },
78
+ };
@@ -1,2 +1,38 @@
1
+ import type { PcInstall } from '../../shared/paths/index.js';
2
+ import type { PcEnv } from '../accounts/index.js';
1
3
  import type { PcInstallSource } from './source.js';
4
+ /** At most this many engines of this PC are mapped. */
5
+ export declare const MAX_PC_ENGINES = 8;
6
+ /** What discovery reads on this PC (the self-test passes fixtures). */
7
+ export interface UnrealPcFiles {
8
+ /** LauncherInstalled.dat's text, or null. */
9
+ readonly launcherInstalled: string | null;
10
+ /** `reg query HKCU\Software\Epic Games\Unreal Engine\Builds` output ('' when the key is missing). */
11
+ readonly builds: string;
12
+ /** The launcher's default engines folder (<Program Files>\Epic Games). */
13
+ readonly defaultRoot: string;
14
+ readonly list: (dir: string) => string[];
15
+ readonly read: (file: string, max: number) => Buffer | null;
16
+ }
17
+ /** The values of `reg query <key>` output: the name and string of each REG_SZ / REG_EXPAND_SZ line. */
18
+ export declare function regValues(text: string): {
19
+ name: string;
20
+ value: string;
21
+ }[];
22
+ /** The engines of this PC that `wanted` maps, each folder once, at most MAX_PC_ENGINES. */
23
+ export declare function findUnrealInstalls(files: UnrealPcFiles, wanted: true | readonly (string | number)[]): PcInstall[];
24
+ /** A source build of this PC's Builds key. */
25
+ export interface PcSourceBuild {
26
+ readonly buildId: string;
27
+ readonly version: string;
28
+ readonly host: string;
29
+ }
30
+ /** Source builds this PC registered (the Builds key). They are not mapped by themselves: UBT writes inside them. */
31
+ export declare function pcSourceBuilds(files: Pick<UnrealPcFiles, 'read' | 'builds'>): PcSourceBuild[];
32
+ /** The engine folders you registered (pcInstalls.unrealEngineFolders), mapped writable. A folder that is a source
33
+ * build of this PC keeps the PC's build id. */
34
+ export declare function findEngineFolders(files: Pick<UnrealPcFiles, 'read' | 'builds'>, folders: readonly (string | number)[]): PcInstall[];
35
+ /** This PC's files (reg.exe through system32, bounded reads). */
36
+ export declare function unrealPcFiles(pc: PcEnv): UnrealPcFiles;
2
37
  export declare const unrealInstalls: PcInstallSource;
38
+ export declare const unrealFolders: PcInstallSource;
@@ -1,7 +1,150 @@
1
+ // Unreal Engine versions of this PC (pcInstalls.unrealEngines): the launcher's LauncherInstalled.dat (engines it
2
+ // installed, with its own ids) and the launcher's default folders (<Program Files>\Epic Games\UE_*, for an install
3
+ // whose LauncherInstalled.dat is gone). Each must hold Engine\Build\Build.version; it is mapped read-only at
4
+ // C:\PcInstalls\unreal\UE_5.4. Source builds (HKCU\Software\Epic Games\Unreal Engine\Builds) are NOT mapped by
5
+ // themselves, as UBT writes inside an engine. pcInstalls.unrealEngineFolders: folders you registered, mapped writable
6
+ // (dir-<name>; a source build of this PC keeps its build id). Every file is read bounded.
7
+ import { spawnSync } from 'node:child_process';
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import { readBoundedFile } from '../../shared/io/index.js';
11
+ import { SYSTEM } from '../../shared/system.js';
12
+ import { BUILDS_KEY, launcherInstallations, launcherInstalledFile, MAX_LAUNCHER_FILE_BYTES, parseBuildVersion, versionText, } from '../../shared/unreal/index.js';
13
+ const win = path.win32;
14
+ /** At most this many engines of this PC are mapped. */
15
+ export const MAX_PC_ENGINES = 8;
16
+ const APP_NAME = /^UE_(\d{1,2}\.\d{1,2})$/;
17
+ /** The values of `reg query <key>` output: the name and string of each REG_SZ / REG_EXPAND_SZ line. */
18
+ export function regValues(text) {
19
+ return text
20
+ .split(/\r?\n/)
21
+ .slice(0, 500)
22
+ .flatMap((line) => {
23
+ const m = /^\s{2,}(\S(?:.{0,200}?\S)?)\s{2,}REG_(?:EXPAND_)?SZ\s{2,}(.{1,1000})$/.exec(line);
24
+ return m ? [{ name: m[1], value: m[2].trim() }] : [];
25
+ });
26
+ }
27
+ const versionOf = (dir, files) => {
28
+ const bytes = files.read(win.join(dir, 'Engine', 'Build', 'Build.version'), 64 * 1024);
29
+ return bytes ? parseBuildVersion(bytes.toString('utf8')) : null;
30
+ };
31
+ const isWanted = (wanted, v) => wanted === true || wanted.map((w) => String(w).replace(/^UE_/i, '')).includes(v.major + '.' + v.minor);
32
+ /** The engines of this PC that `wanted` maps, each folder once, at most MAX_PC_ENGINES. */
33
+ export function findUnrealInstalls(files, wanted) {
34
+ const found = [];
35
+ const add = (install) => {
36
+ const key = win.resolve(install.host).toLowerCase();
37
+ if (found.length >= MAX_PC_ENGINES)
38
+ return;
39
+ if (found.some((f) => f.id === install.id || win.resolve(f.host).toLowerCase() === key))
40
+ return;
41
+ found.push(install);
42
+ };
43
+ const installed = (dir, ids) => {
44
+ const v = versionOf(dir, files);
45
+ if (!v || !isWanted(wanted, v))
46
+ return;
47
+ add({
48
+ kind: 'unreal',
49
+ id: 'UE_' + v.major + '.' + v.minor,
50
+ name: 'Unreal Engine ' + versionText(v),
51
+ version: versionText(v),
52
+ host: win.normalize(dir),
53
+ guest: '',
54
+ ...(ids ? { launcher: ids } : {}),
55
+ });
56
+ };
57
+ for (const i of files.launcherInstalled ? launcherInstallations(files.launcherInstalled) : [])
58
+ if (APP_NAME.test(i.appName))
59
+ installed(i.installLocation, i.ids ?? undefined);
60
+ for (const name of files
61
+ .list(files.defaultRoot)
62
+ .filter((n) => APP_NAME.test(n))
63
+ .sort())
64
+ installed(win.join(files.defaultRoot, name));
65
+ return found;
66
+ }
67
+ /** Source builds this PC registered (the Builds key). They are not mapped by themselves: UBT writes inside them. */
68
+ export function pcSourceBuilds(files) {
69
+ const found = [];
70
+ for (const { name, value } of regValues(files.builds)) {
71
+ const dir = value.replace(/\//g, '\\');
72
+ if (!win.isAbsolute(dir) || found.length >= MAX_PC_ENGINES)
73
+ continue;
74
+ const v = versionOf(dir, files);
75
+ if (v)
76
+ found.push({ buildId: name.slice(0, 64), version: versionText(v), host: win.normalize(dir) });
77
+ }
78
+ return found;
79
+ }
80
+ /** The engine folders you registered (pcInstalls.unrealEngineFolders), mapped writable. A folder that is a source
81
+ * build of this PC keeps the PC's build id. */
82
+ export function findEngineFolders(files, folders) {
83
+ const found = [];
84
+ const sources = pcSourceBuilds(files);
85
+ for (const raw of folders.map(String)) {
86
+ const dir = win.normalize(raw);
87
+ if (!win.isAbsolute(dir) || found.some((f) => f.host.toLowerCase() === dir.toLowerCase()))
88
+ continue;
89
+ const v = versionOf(dir, files);
90
+ if (!v)
91
+ continue;
92
+ const base = win
93
+ .basename(dir)
94
+ .replace(/[^A-Za-z0-9._-]/g, '')
95
+ .replace(/^\.+/, '')
96
+ .slice(0, 40) || 'engine';
97
+ const id = 'dir-' + base;
98
+ const source = sources.find((b) => b.host.toLowerCase() === dir.toLowerCase());
99
+ found.push({
100
+ kind: 'unreal',
101
+ id: found.some((f) => f.id === id) ? id + '-' + (found.length + 1) : id,
102
+ name: 'Unreal Engine ' + versionText(v) + ' (' + win.basename(dir).slice(0, 60) + ')',
103
+ version: versionText(v),
104
+ host: dir,
105
+ guest: '',
106
+ writable: true,
107
+ ...(source ? { buildId: source.buildId } : {}),
108
+ });
109
+ }
110
+ return found;
111
+ }
112
+ function listDir(dir) {
113
+ try {
114
+ return fs.readdirSync(dir).slice(0, 500);
115
+ }
116
+ catch {
117
+ return []; // Not there: nothing in it.
118
+ }
119
+ }
120
+ /** This PC's files (reg.exe through system32, bounded reads). */
121
+ export function unrealPcFiles(pc) {
122
+ const query = spawnSync(SYSTEM.reg(), ['query', 'HKCU\\' + BUILDS_KEY], {
123
+ encoding: 'utf8',
124
+ windowsHide: true,
125
+ timeout: 15_000,
126
+ maxBuffer: 256 * 1024,
127
+ });
128
+ const dat = readBoundedFile(launcherInstalledFile(pc.programData), MAX_LAUNCHER_FILE_BYTES);
129
+ return {
130
+ launcherInstalled: dat ? dat.toString('utf8') : null,
131
+ builds: query.status === 0 ? String(query.stdout ?? '') : '',
132
+ defaultRoot: win.join(pc.programFiles ?? 'C:\\Program Files', 'Epic Games'),
133
+ list: listDir,
134
+ read: readBoundedFile,
135
+ };
136
+ }
1
137
  export const unrealInstalls = {
2
138
  kind: 'unreal',
3
139
  setting: 'unrealEngines',
4
- find(_wanted, _pc) {
5
- return [];
140
+ find(wanted, pc) {
141
+ return findUnrealInstalls(unrealPcFiles(pc), wanted);
142
+ },
143
+ };
144
+ export const unrealFolders = {
145
+ kind: 'unreal',
146
+ setting: 'unrealEngineFolders',
147
+ find(wanted, pc) {
148
+ return wanted === true ? [] : findEngineFolders(unrealPcFiles(pc), wanted);
6
149
  },
7
150
  };
@@ -1,5 +1,13 @@
1
1
  import type { ClaudeProfileConfig, ProfileResult } from '../../core/types.js';
2
2
  import { type SecretsConfig } from './secrets.js';
3
+ /**
4
+ * Which parts of your plugins folder are staged, as a filter over full paths. Everything Claude needs to load a plugin
5
+ * (installed_plugins.json, marketplaces, the plugin cache) is kept; when that is over the size cap, git history
6
+ * (`.git`) and then `node_modules` are left out, and the guest's plugins restore what they need on first use.
7
+ */
8
+ export declare function pluginFilter(source: string, level: 0 | 1 | 2): (full: string) => boolean;
9
+ /** The least trimmed level at which the plugins folder fits the cap, or null when even the most trimmed does not. */
10
+ export declare function pluginTrimLevel(source: string): 0 | 1 | 2 | null;
3
11
  export declare function hostClaudeDir(settings: ClaudeProfileConfig): string;
4
12
  export declare function hostGlobalStateFile(settings: ClaudeProfileConfig): string;
5
13
  /**
@@ -5,17 +5,54 @@ import { dirExists, ensureDir, fileExists, homeDir, isLink, readJson, writeJson
5
5
  import { stripMcpServers, stripSettings } from './secrets.js';
6
6
  const MAX_BYTES = 250 * 1024 * 1024;
7
7
  /** Real files only: a link inside ~/.claude (even a loop or a dead one) is neither followed nor counted nor copied. */
8
- function directorySize(dir) {
8
+ function directorySize(dir, keep = () => true) {
9
9
  let total = 0;
10
10
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
11
11
  const full = path.join(dir, entry.name);
12
+ if (!keep(full))
13
+ continue;
12
14
  if (entry.isDirectory())
13
- total += directorySize(full);
15
+ total += directorySize(full, keep);
14
16
  else if (entry.isFile())
15
17
  total += fs.statSync(full).size;
16
18
  }
17
19
  return total;
18
20
  }
21
+ /** Plugin leftovers Claude never reads: interrupted clones (temp_*) and marketplace backups. */
22
+ function isPluginJunk(parts) {
23
+ const top = parts[0]?.toLowerCase();
24
+ const name = parts[1]?.toLowerCase() ?? '';
25
+ return (parts.length >= 2 &&
26
+ (top === 'cache' || top === 'marketplaces') &&
27
+ (name.startsWith('temp_') || name.endsWith('.backup') || name.endsWith('.staging')));
28
+ }
29
+ /**
30
+ * Which parts of your plugins folder are staged, as a filter over full paths. Everything Claude needs to load a plugin
31
+ * (installed_plugins.json, marketplaces, the plugin cache) is kept; when that is over the size cap, git history
32
+ * (`.git`) and then `node_modules` are left out, and the guest's plugins restore what they need on first use.
33
+ */
34
+ export function pluginFilter(source, level) {
35
+ return (full) => {
36
+ if (full === source)
37
+ return true;
38
+ const parts = path.relative(source, full).split(path.sep);
39
+ if (isPluginJunk(parts))
40
+ return false;
41
+ if (level >= 1 && parts.includes('.git'))
42
+ return false;
43
+ if (level >= 2 && parts.includes('node_modules'))
44
+ return false;
45
+ return true;
46
+ };
47
+ }
48
+ /** The least trimmed level at which the plugins folder fits the cap, or null when even the most trimmed does not. */
49
+ export function pluginTrimLevel(source) {
50
+ for (const level of [0, 1, 2]) {
51
+ if (directorySize(source, pluginFilter(source, level)) <= MAX_BYTES)
52
+ return level;
53
+ }
54
+ return null;
55
+ }
19
56
  function validJson(file) {
20
57
  try {
21
58
  JSON.parse(fs.readFileSync(file, 'utf8').replace(/^\uFEFF/, ''));
@@ -84,14 +121,16 @@ export function stageClaudeProfile(settings, launchPath, workspaceHost, secrets)
84
121
  fs.copyFileSync(source, destination);
85
122
  }
86
123
  else if (dirExists(source)) {
87
- if (directorySize(source) > MAX_BYTES) {
124
+ const level = name === 'plugins' ? pluginTrimLevel(source) : directorySize(source) > MAX_BYTES ? null : 0;
125
+ if (level === null) {
88
126
  result.skipped.push(name + ' (over 250 MB)');
89
127
  continue;
90
128
  }
129
+ const keep = name === 'plugins' ? pluginFilter(source, level) : () => true;
91
130
  fs.cpSync(source, destination, {
92
131
  recursive: true,
93
132
  force: true,
94
- filter: (from) => from === source || !isLink(from),
133
+ filter: (from) => from === source || (!isLink(from) && keep(from)),
95
134
  });
96
135
  }
97
136
  else {
@@ -1,6 +1,6 @@
1
1
  export { isSecretName, isSecretValue, mayPass, stripMcpServers, stripSettings, stripVariables, type SecretsConfig, } from './secrets.js';
2
2
  export { findSecretFiles } from './secret-files.js';
3
- export { hostClaudeDir, hostGlobalStateFile, sandboxGlobalState, stageClaudeProfile } from './claude-profile.js';
3
+ export { hostClaudeDir, hostGlobalStateFile, pluginFilter, pluginTrimLevel, sandboxGlobalState, stageClaudeProfile, } from './claude-profile.js';
4
4
  export { capturePersonalization } from './personalize.js';
5
5
  export { toRegFile, type RegValue } from './reg-file.js';
6
6
  export { AccountStore, accountsDir, type Account, type AccountMeta, type AccountRow } from './accounts.js';
@@ -1,6 +1,6 @@
1
1
  export { isSecretName, isSecretValue, mayPass, stripMcpServers, stripSettings, stripVariables, } from './secrets.js';
2
2
  export { findSecretFiles } from './secret-files.js';
3
- export { hostClaudeDir, hostGlobalStateFile, sandboxGlobalState, stageClaudeProfile } from './claude-profile.js';
3
+ export { hostClaudeDir, hostGlobalStateFile, pluginFilter, pluginTrimLevel, sandboxGlobalState, stageClaudeProfile, } from './claude-profile.js';
4
4
  export { capturePersonalization } from './personalize.js';
5
5
  export { toRegFile } from './reg-file.js';
6
6
  export { AccountStore, accountsDir } from './accounts.js';