windows-development-sandbox 1.17.3 → 1.18.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 (315) hide show
  1. package/README.md +1 -1
  2. package/config.example.json +97 -4
  3. package/dist/app/features/accounts/accounts.def.d.ts +116 -2
  4. package/dist/app/features/accounts/accounts.def.js +80 -12
  5. package/dist/app/features/accounts/accounts.run.d.ts +29 -0
  6. package/dist/app/features/accounts/accounts.run.js +36 -6
  7. package/dist/app/features/accounts/index.d.ts +2 -0
  8. package/dist/app/features/accounts/index.js +4 -1
  9. package/dist/app/features/accounts/services.def.d.ts +111 -0
  10. package/dist/app/features/accounts/services.def.js +187 -0
  11. package/dist/app/features/accounts/services.run.d.ts +65 -0
  12. package/dist/app/features/accounts/services.run.js +212 -0
  13. package/dist/app/features/defs.d.ts +112 -1
  14. package/dist/app/features/defs.js +5 -0
  15. package/dist/app/features/settings/categories.def.js +21 -4
  16. package/dist/app/registry.js +5 -1
  17. package/dist/bin/agent-sandbox.js +2 -2
  18. package/dist/bin/{chunk-QLGGAG3D.js → chunk-BKF43GJ3.js} +51 -16
  19. package/dist/bin/{chunk-REE3EMHD.js → chunk-YD3A67RS.js} +3812 -1702
  20. package/dist/bin/{chunk-XYUVIVJT.js → chunk-Z5D32FN3.js} +1 -1
  21. package/dist/bin/claude-host.js +2 -2
  22. package/dist/bin/claude-sbx.js +2 -2
  23. package/dist/bin/codex-sbx.js +2 -2
  24. package/dist/bin/gemini-sbx.js +2 -2
  25. package/dist/bin/sandbox.js +2 -2
  26. package/dist/bin/sbx-hide.js +2 -2
  27. package/dist/bin/sbx-show.js +2 -2
  28. package/dist/cli/commands/launch/launch.js +30 -1
  29. package/dist/cli/manifest.d.ts +93 -65
  30. package/dist/cli/manifest.js +23 -5
  31. package/dist/cli/menu/pages/accounts-page.js +31 -16
  32. package/dist/cli/services/accounts-service.d.ts +14 -4
  33. package/dist/cli/services/accounts-service.js +19 -6
  34. package/dist/cli/services/data-collect.js +26 -1
  35. package/dist/core/config/defaults.js +47 -4
  36. package/dist/core/detect/toolchains.d.ts +15 -1
  37. package/dist/core/detect/toolchains.js +45 -12
  38. package/dist/core/local-config/overrides.js +6 -0
  39. package/dist/core/schema/accounts.d.ts +27 -0
  40. package/dist/core/schema/accounts.js +32 -0
  41. package/dist/core/schema/config.d.ts +239 -0
  42. package/dist/core/schema/config.js +6 -0
  43. package/dist/core/schema/pc-installs.d.ts +7 -0
  44. package/dist/core/schema/pc-installs.js +17 -0
  45. package/dist/core/schema/toolchains.d.ts +61 -0
  46. package/dist/core/schema/toolchains.js +106 -0
  47. package/dist/core/types.d.ts +18 -0
  48. package/dist/guest/accounts/adapter.d.ts +25 -0
  49. package/dist/guest/accounts/adapter.js +21 -0
  50. package/dist/guest/accounts/adapters.d.ts +5 -0
  51. package/dist/guest/accounts/adapters.js +18 -0
  52. package/dist/guest/accounts/apply.d.ts +41 -0
  53. package/dist/guest/accounts/apply.js +47 -0
  54. package/dist/guest/accounts/kinds/appstore.d.ts +2 -0
  55. package/dist/guest/accounts/kinds/appstore.js +7 -0
  56. package/dist/guest/accounts/kinds/cfx.d.ts +2 -0
  57. package/dist/guest/accounts/kinds/cfx.js +7 -0
  58. package/dist/guest/accounts/kinds/epic.d.ts +2 -0
  59. package/dist/guest/accounts/kinds/epic.js +26 -0
  60. package/dist/guest/accounts/kinds/expo.d.ts +2 -0
  61. package/dist/guest/accounts/kinds/expo.js +7 -0
  62. package/dist/guest/accounts/kinds/keystore.d.ts +2 -0
  63. package/dist/guest/accounts/kinds/keystore.js +7 -0
  64. package/dist/guest/accounts/kinds/play.d.ts +2 -0
  65. package/dist/guest/accounts/kinds/play.js +7 -0
  66. package/dist/guest/accounts/kinds/steam.d.ts +4 -0
  67. package/dist/guest/accounts/kinds/steam.js +17 -0
  68. package/dist/guest/accounts/kinds/unity.d.ts +2 -0
  69. package/dist/guest/accounts/kinds/unity.js +7 -0
  70. package/dist/guest/accounts/watch.d.ts +28 -0
  71. package/dist/guest/accounts/watch.js +78 -0
  72. package/dist/guest/apps/resolvers-gamedev.d.ts +2 -0
  73. package/dist/guest/apps/resolvers-gamedev.js +1 -0
  74. package/dist/guest/apps/resolvers-mobile.d.ts +2 -0
  75. package/dist/guest/apps/resolvers-mobile.js +1 -0
  76. package/dist/guest/apps/resolvers.js +4 -0
  77. package/dist/guest/boot/boot.d.ts +5 -0
  78. package/dist/guest/boot/boot.js +35 -1
  79. package/dist/guest/daemon/accounts.d.ts +3 -0
  80. package/dist/guest/daemon/accounts.js +25 -0
  81. package/dist/guest/daemon/daemon.js +2 -0
  82. package/dist/guest/daemon/idle-shutdown.js +3 -1
  83. package/dist/guest/daemon/sessions.js +2 -0
  84. package/dist/guest/devtools/android.d.ts +2 -0
  85. package/dist/guest/devtools/android.js +7 -0
  86. package/dist/guest/devtools/devtool.d.ts +9 -0
  87. package/dist/guest/devtools/devtool.js +5 -0
  88. package/dist/guest/devtools/fivem.d.ts +2 -0
  89. package/dist/guest/devtools/fivem.js +7 -0
  90. package/dist/guest/devtools/registry.d.ts +6 -0
  91. package/dist/guest/devtools/registry.js +12 -0
  92. package/dist/guest/devtools/steam.d.ts +2 -0
  93. package/dist/guest/devtools/steam.js +228 -0
  94. package/dist/guest/devtools/unity.d.ts +2 -0
  95. package/dist/guest/devtools/unity.js +7 -0
  96. package/dist/guest/entries/daemon.js +2 -0
  97. package/dist/guest/entries/tool.d.ts +1 -0
  98. package/dist/guest/entries/tool.js +17 -0
  99. package/dist/guest/toolchains/engines/godot.d.ts +4 -0
  100. package/dist/guest/toolchains/engines/godot.js +4 -0
  101. package/dist/guest/toolchains/engines/unity-release.d.ts +15 -0
  102. package/dist/guest/toolchains/engines/unity-release.js +6 -0
  103. package/dist/guest/toolchains/engines/unity.d.ts +4 -0
  104. package/dist/guest/toolchains/engines/unity.js +4 -0
  105. package/dist/guest/toolchains/engines/unreal-engines.d.ts +4 -0
  106. package/dist/guest/toolchains/engines/unreal-engines.js +4 -0
  107. package/dist/guest/toolchains/fivem/artifacts.d.ts +6 -0
  108. package/dist/guest/toolchains/fivem/artifacts.js +7 -0
  109. package/dist/guest/toolchains/fivem/fivem.d.ts +4 -0
  110. package/dist/guest/toolchains/fivem/fivem.js +4 -0
  111. package/dist/guest/toolchains/installers.d.ts +12 -0
  112. package/dist/guest/toolchains/installers.js +39 -0
  113. package/dist/guest/toolchains/languages/java.js +1 -1
  114. package/dist/guest/toolchains/languages/kotlin.d.ts +3 -0
  115. package/dist/guest/toolchains/languages/kotlin.js +6 -0
  116. package/dist/guest/toolchains/mobile/android-repo.d.ts +11 -0
  117. package/dist/guest/toolchains/mobile/android-repo.js +10 -0
  118. package/dist/guest/toolchains/mobile/android.d.ts +17 -0
  119. package/dist/guest/toolchains/mobile/android.js +16 -0
  120. package/dist/guest/toolchains/mobile/dart.d.ts +4 -0
  121. package/dist/guest/toolchains/mobile/dart.js +4 -0
  122. package/dist/guest/toolchains/mobile/flutter.d.ts +4 -0
  123. package/dist/guest/toolchains/mobile/flutter.js +4 -0
  124. package/dist/guest/toolchains/mobile/react-native.d.ts +4 -0
  125. package/dist/guest/toolchains/mobile/react-native.js +4 -0
  126. package/dist/guest/toolchains/native/unreal.d.ts +3 -7
  127. package/dist/guest/toolchains/native/unreal.js +16 -167
  128. package/dist/guest/toolchains/native/visual-studio.d.ts +15 -0
  129. package/dist/guest/toolchains/native/visual-studio.js +159 -0
  130. package/dist/guest/toolchains/native/vs-request.d.ts +19 -0
  131. package/dist/guest/toolchains/native/vs-request.js +46 -0
  132. package/dist/guest/toolchains/not-yet.d.ts +2 -0
  133. package/dist/guest/toolchains/not-yet.js +6 -0
  134. package/dist/guest/toolchains/persisted.d.ts +48 -0
  135. package/dist/guest/toolchains/persisted.js +159 -0
  136. package/dist/guest/toolchains/plan.js +80 -4
  137. package/dist/guest/toolchains/steam/apps.d.ts +27 -0
  138. package/dist/guest/toolchains/steam/apps.js +112 -0
  139. package/dist/guest/toolchains/steam/client.d.ts +5 -0
  140. package/dist/guest/toolchains/steam/client.js +67 -0
  141. package/dist/guest/toolchains/steam/commands.d.ts +58 -0
  142. package/dist/guest/toolchains/steam/commands.js +155 -0
  143. package/dist/guest/toolchains/steam/steam.d.ts +4 -0
  144. package/dist/guest/toolchains/steam/steam.js +61 -0
  145. package/dist/guest/toolchains/steam/steamcmd-install.d.ts +29 -0
  146. package/dist/guest/toolchains/steam/steamcmd-install.js +177 -0
  147. package/dist/guest/toolchains/steam/steamcmd.d.ts +6 -0
  148. package/dist/guest/toolchains/steam/steamcmd.js +23 -0
  149. package/dist/guest/toolchains/step.d.ts +10 -0
  150. package/dist/host/accounts/deliver.d.ts +26 -0
  151. package/dist/host/accounts/deliver.js +80 -0
  152. package/dist/host/accounts/handoff.d.ts +17 -0
  153. package/dist/host/accounts/handoff.js +110 -0
  154. package/dist/host/accounts/index.d.ts +6 -0
  155. package/dist/host/accounts/index.js +8 -0
  156. package/dist/host/accounts/kinds/appstore.d.ts +2 -0
  157. package/dist/host/accounts/kinds/appstore.js +10 -0
  158. package/dist/host/accounts/kinds/cfx.d.ts +2 -0
  159. package/dist/host/accounts/kinds/cfx.js +7 -0
  160. package/dist/host/accounts/kinds/epic.d.ts +2 -0
  161. package/dist/host/accounts/kinds/epic.js +15 -0
  162. package/dist/host/accounts/kinds/expo.d.ts +2 -0
  163. package/dist/host/accounts/kinds/expo.js +7 -0
  164. package/dist/host/accounts/kinds/keystore.d.ts +2 -0
  165. package/dist/host/accounts/kinds/keystore.js +7 -0
  166. package/dist/host/accounts/kinds/play.d.ts +2 -0
  167. package/dist/host/accounts/kinds/play.js +7 -0
  168. package/dist/host/accounts/kinds/steam.d.ts +6 -0
  169. package/dist/host/accounts/kinds/steam.js +31 -0
  170. package/dist/host/accounts/kinds/unity.d.ts +2 -0
  171. package/dist/host/accounts/kinds/unity.js +13 -0
  172. package/dist/host/accounts/leases.d.ts +40 -0
  173. package/dist/host/accounts/leases.js +62 -0
  174. package/dist/host/accounts/source.d.ts +21 -0
  175. package/dist/host/accounts/source.js +15 -0
  176. package/dist/host/accounts/sources.d.ts +5 -0
  177. package/dist/host/accounts/sources.js +18 -0
  178. package/dist/host/accounts/store.d.ts +23 -0
  179. package/dist/host/accounts/store.js +74 -0
  180. package/dist/host/audit/log.d.ts +1 -1
  181. package/dist/host/launch/generate.d.ts +2 -0
  182. package/dist/host/launch/generate.js +16 -1
  183. package/dist/host/launch/hints/android.d.ts +3 -0
  184. package/dist/host/launch/hints/android.js +3 -0
  185. package/dist/host/launch/hints/engines.d.ts +3 -0
  186. package/dist/host/launch/hints/engines.js +3 -0
  187. package/dist/host/launch/hints/fivem.d.ts +3 -0
  188. package/dist/host/launch/hints/fivem.js +3 -0
  189. package/dist/host/launch/hints/hint.d.ts +2 -0
  190. package/dist/host/launch/hints/hint.js +1 -0
  191. package/dist/host/launch/hints/index.d.ts +5 -0
  192. package/dist/host/launch/hints/index.js +29 -0
  193. package/dist/host/launch/hints/mobile.d.ts +3 -0
  194. package/dist/host/launch/hints/mobile.js +3 -0
  195. package/dist/host/launch/hints/steam.d.ts +7 -0
  196. package/dist/host/launch/hints/steam.js +59 -0
  197. package/dist/host/launch/index.d.ts +2 -2
  198. package/dist/host/launch/index.js +2 -2
  199. package/dist/host/launch/mappings.js +2 -0
  200. package/dist/host/launch/session-file.js +2 -0
  201. package/dist/host/launch/stage.js +10 -1
  202. package/dist/host/launch/toolchains.d.ts +7 -0
  203. package/dist/host/launch/toolchains.js +11 -0
  204. package/dist/host/pc-installs/discover.d.ts +19 -0
  205. package/dist/host/pc-installs/discover.js +59 -0
  206. package/dist/host/pc-installs/epic.d.ts +2 -0
  207. package/dist/host/pc-installs/epic.js +7 -0
  208. package/dist/host/pc-installs/index.d.ts +3 -0
  209. package/dist/host/pc-installs/index.js +2 -0
  210. package/dist/host/pc-installs/source.d.ts +9 -0
  211. package/dist/host/pc-installs/source.js +1 -0
  212. package/dist/host/pc-installs/steam.d.ts +16 -0
  213. package/dist/host/pc-installs/steam.js +143 -0
  214. package/dist/host/pc-installs/unity.d.ts +2 -0
  215. package/dist/host/pc-installs/unity.js +7 -0
  216. package/dist/host/pc-installs/unreal.d.ts +2 -0
  217. package/dist/host/pc-installs/unreal.js +7 -0
  218. package/dist/host/profile/accounts.d.ts +21 -6
  219. package/dist/host/profile/accounts.js +108 -28
  220. package/dist/host/profile/claude-login.d.ts +32 -2
  221. package/dist/host/profile/claude-login.js +100 -8
  222. package/dist/host/profile/index.d.ts +1 -1
  223. package/dist/host/profile/index.js +1 -1
  224. package/dist/host/secrets/launch-secrets.js +1 -0
  225. package/dist/runtime/agent.js +321 -9
  226. package/dist/runtime/daemon.js +1987 -604
  227. package/dist/runtime/db.js +334 -11
  228. package/dist/runtime/main.js +2519 -723
  229. package/dist/runtime/netproxy.js +321 -9
  230. package/dist/runtime/tool.js +28549 -0
  231. package/dist/runtime/view.js +321 -9
  232. package/dist/selftest/accounts.test.js +172 -1
  233. package/dist/selftest/agent-paths.test.js +1 -0
  234. package/dist/selftest/android.test.d.ts +2 -0
  235. package/dist/selftest/android.test.js +7 -0
  236. package/dist/selftest/app.test.js +1 -1
  237. package/dist/selftest/engines.test.d.ts +2 -0
  238. package/dist/selftest/engines.test.js +7 -0
  239. package/dist/selftest/fivem.test.d.ts +2 -0
  240. package/dist/selftest/fivem.test.js +7 -0
  241. package/dist/selftest/generate.test.js +1 -1
  242. package/dist/selftest/index.js +18 -0
  243. package/dist/selftest/menu-screens.js +1 -0
  244. package/dist/selftest/menu.test.js +2 -1
  245. package/dist/selftest/mobile.test.d.ts +2 -0
  246. package/dist/selftest/mobile.test.js +7 -0
  247. package/dist/selftest/pc-installs.test.d.ts +2 -0
  248. package/dist/selftest/pc-installs.test.js +111 -0
  249. package/dist/selftest/persisted-installs.test.d.ts +2 -0
  250. package/dist/selftest/persisted-installs.test.js +107 -0
  251. package/dist/selftest/projects.test.js +6 -4
  252. package/dist/selftest/service-accounts.test.d.ts +2 -0
  253. package/dist/selftest/service-accounts.test.js +320 -0
  254. package/dist/selftest/steam.test.d.ts +2 -0
  255. package/dist/selftest/steam.test.js +316 -0
  256. package/dist/selftest/storage-helper.test.js +31 -8
  257. package/dist/selftest/support/engine-golden.js +3 -0
  258. package/dist/selftest/support/fixtures.d.ts +87 -0
  259. package/dist/selftest/support/fixtures.js +4 -3
  260. package/dist/selftest/support/pc-memory.d.ts +2 -0
  261. package/dist/selftest/support/pc-memory.js +17 -0
  262. package/dist/selftest/support/web-preview.js +20 -1
  263. package/dist/selftest/unity.test.d.ts +2 -0
  264. package/dist/selftest/unity.test.js +7 -0
  265. package/dist/shared/accounts/fingerprint.d.ts +1 -0
  266. package/dist/shared/accounts/fingerprint.js +20 -0
  267. package/dist/shared/accounts/index.d.ts +5 -0
  268. package/dist/shared/accounts/index.js +7 -0
  269. package/dist/shared/accounts/kinds/epic.d.ts +10 -0
  270. package/dist/shared/accounts/kinds/epic.js +56 -0
  271. package/dist/shared/accounts/kinds/steam.d.ts +28 -0
  272. package/dist/shared/accounts/kinds/steam.js +99 -0
  273. package/dist/shared/accounts/kinds.d.ts +41 -0
  274. package/dist/shared/accounts/kinds.js +154 -0
  275. package/dist/shared/accounts/payloads.d.ts +151 -0
  276. package/dist/shared/accounts/payloads.js +128 -0
  277. package/dist/shared/apps/catalogue-gamedev.d.ts +2 -0
  278. package/dist/shared/apps/catalogue-gamedev.js +1 -0
  279. package/dist/shared/apps/catalogue-mobile.d.ts +2 -0
  280. package/dist/shared/apps/catalogue-mobile.js +1 -0
  281. package/dist/shared/apps/catalogue-modding.d.ts +2 -0
  282. package/dist/shared/apps/catalogue-modding.js +1 -0
  283. package/dist/shared/apps/catalogue.d.ts +1 -0
  284. package/dist/shared/apps/catalogue.js +6 -1
  285. package/dist/shared/channel/schema.d.ts +183 -0
  286. package/dist/shared/channel/secrets.d.ts +42 -0
  287. package/dist/shared/channel/secrets.js +3 -0
  288. package/dist/shared/download/downloader.d.ts +7 -0
  289. package/dist/shared/download/downloader.js +10 -3
  290. package/dist/shared/installs.d.ts +19 -0
  291. package/dist/shared/installs.js +13 -0
  292. package/dist/shared/io/bounded.d.ts +6 -0
  293. package/dist/shared/io/bounded.js +38 -0
  294. package/dist/shared/io/index.d.ts +2 -0
  295. package/dist/shared/io/index.js +2 -0
  296. package/dist/shared/io/text.d.ts +9 -0
  297. package/dist/shared/io/text.js +18 -0
  298. package/dist/shared/paths/guest-paths.js +1 -1
  299. package/dist/shared/paths/index.d.ts +1 -0
  300. package/dist/shared/paths/index.js +1 -0
  301. package/dist/shared/paths/pc-installs.d.ts +20 -0
  302. package/dist/shared/paths/pc-installs.js +19 -0
  303. package/dist/shared/vdf.d.ts +25 -0
  304. package/dist/shared/vdf.js +151 -0
  305. package/dist/sync/sync-cycle.js +9 -0
  306. package/dist/web/index.html +1 -1
  307. package/dist/web/{main-JTH3FT4O.js → main-CWIF4VQI.js} +63 -61
  308. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  309. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  310. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  311. package/package.json +1 -1
  312. package/sandbox/scripts/add-firewall-port.ps1 +13 -0
  313. package/sandbox/templates/fivem/README.txt +2 -0
  314. package/schemas/config.schema.json +485 -0
  315. package/schemas/sandbox-config.schema.json +416 -0
@@ -0,0 +1,20 @@
1
+ // The fingerprint of a sign-in: a SHA-256 of its canonical JSON (keys sorted), so the sandbox can tell a renewed one
2
+ // from the one it was given without keeping either around. Node only (not for the web bundle).
3
+ import crypto from 'node:crypto';
4
+ /** JSON with every object's keys sorted, so equal values always give equal text. */
5
+ function canonical(value) {
6
+ if (Array.isArray(value))
7
+ return '[' + value.map(canonical).join(',') + ']';
8
+ if (value && typeof value === 'object')
9
+ return ('{' +
10
+ Object.keys(value)
11
+ .filter((k) => value[k] !== undefined)
12
+ .sort()
13
+ .map((k) => JSON.stringify(k) + ':' + canonical(value[k]))
14
+ .join(',') +
15
+ '}');
16
+ return JSON.stringify(value) ?? 'null';
17
+ }
18
+ export function fingerprint(payload) {
19
+ return crypto.createHash('sha256').update(canonical(payload)).digest('hex');
20
+ }
@@ -0,0 +1,5 @@
1
+ export * from './kinds.js';
2
+ export * from './payloads.js';
3
+ export { fingerprint } from './fingerprint.js';
4
+ export { epicSettingsFile, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin, type EpicPayload } from './kinds/epic.js';
5
+ export * from './kinds/steam.js';
@@ -0,0 +1,7 @@
1
+ // Service sign-ins kept for sandboxes (accounts.<kind>.share): the kinds, their payloads, the fingerprint and the
2
+ // Epic launcher's ini handling. kinds.ts and payloads.ts are web-safe; fingerprint.ts needs node:crypto.
3
+ export * from './kinds.js';
4
+ export * from './payloads.js';
5
+ export { fingerprint } from './fingerprint.js';
6
+ export { epicSettingsFile, MAX_EPIC_INI_BYTES, readEpicLogin, withEpicLogin } from './kinds/epic.js';
7
+ export * from './kinds/steam.js';
@@ -0,0 +1,10 @@
1
+ import type { Payload } from '../payloads.js';
2
+ /** At most this much of a GameUserSettings.ini is read. */
3
+ export declare const MAX_EPIC_INI_BYTES: number;
4
+ export type EpicPayload = Payload<'epic'>;
5
+ /** GameUserSettings.ini under a LocalAppData folder (the PC's or the sandbox's). */
6
+ export declare function epicSettingsFile(localAppData: string): string;
7
+ /** The saved sign-in in an ini text, or null (none, turned off, or not the expected shape). */
8
+ export declare function readEpicLogin(ini: string): EpicPayload | null;
9
+ /** The ini text with its [RememberMe] section replaced by this sign-in (the other sections are kept). */
10
+ export declare function withEpicLogin(ini: string, login: EpicPayload): string;
@@ -0,0 +1,56 @@
1
+ // The Epic Games Launcher's saved sign-in ("Remember me"): the Data value of the [RememberMe] section of its
2
+ // GameUserSettings.ini. Pure text handling for the host (taking this PC's) and the sandbox (writing it in at boot,
3
+ // noticing when the launcher renews it). Read line by line: the sandbox may have written the file. The file is often
4
+ // UTF-16: callers decode it with shared/io/text.ts and write it back in the encoding they read.
5
+ import { EpicPayloadSchema } from '../payloads.js';
6
+ /** At most this much of a GameUserSettings.ini is read. */
7
+ export const MAX_EPIC_INI_BYTES = 1024 * 1024;
8
+ const SECTION = '[rememberme]';
9
+ /** GameUserSettings.ini under a LocalAppData folder (the PC's or the sandbox's). */
10
+ export function epicSettingsFile(localAppData) {
11
+ return localAppData + '\\EpicGamesLauncher\\Saved\\Config\\Windows\\GameUserSettings.ini';
12
+ }
13
+ const isHeader = (line) => line.trimStart().startsWith('[');
14
+ /** The saved sign-in in an ini text, or null (none, turned off, or not the expected shape). */
15
+ export function readEpicLogin(ini) {
16
+ let inSection = false;
17
+ let enabled = true;
18
+ let data = null;
19
+ for (const raw of ini.split(/\r?\n/)) {
20
+ const line = raw.trim();
21
+ if (isHeader(line)) {
22
+ inSection = line.toLowerCase() === SECTION;
23
+ continue;
24
+ }
25
+ if (!inSection)
26
+ continue;
27
+ const at = line.indexOf('=');
28
+ if (at < 0)
29
+ continue;
30
+ const key = line.slice(0, at).trim().toLowerCase();
31
+ const value = line.slice(at + 1).trim();
32
+ if (key === 'enable')
33
+ enabled = value.toLowerCase() === 'true';
34
+ else if (key === 'data')
35
+ data = value;
36
+ }
37
+ if (!enabled || !data)
38
+ return null;
39
+ const parsed = EpicPayloadSchema.safeParse({ data });
40
+ return parsed.success ? parsed.data : null;
41
+ }
42
+ /** The ini text with its [RememberMe] section replaced by this sign-in (the other sections are kept). */
43
+ export function withEpicLogin(ini, login) {
44
+ const kept = [];
45
+ let inSection = false;
46
+ for (const line of ini.split(/\r?\n/)) {
47
+ if (isHeader(line))
48
+ inSection = line.trim().toLowerCase() === SECTION;
49
+ if (!inSection)
50
+ kept.push(line);
51
+ }
52
+ while (kept.length && kept[kept.length - 1].trim() === '')
53
+ kept.pop();
54
+ const section = ['[RememberMe]', 'Enable=True', 'Data=' + EpicPayloadSchema.parse(login).data];
55
+ return [...kept, ...(kept.length ? [''] : []), ...section, ''].join('\r\n');
56
+ }
@@ -0,0 +1,28 @@
1
+ import { type Payload } from '../payloads.js';
2
+ export type SteamPayload = Payload<'steam'>;
3
+ /** At most this much of config.vdf is read (the payload's limit). */
4
+ export declare const MAX_STEAM_CONFIG_BYTES: number;
5
+ /** A sentry's bytes (its base64 fits the payload's 64 KB). */
6
+ export declare const MAX_SENTRY_BYTES: number;
7
+ export declare const STEAM_ACCOUNT: RegExp;
8
+ /** The file SteamCMD's folder keeps the account name in (sbx-steam writes it; config.vdf may not say it). */
9
+ export declare const STEAM_ACCOUNT_FILE = "sbx-account.txt";
10
+ export declare function steamConfigFile(steamcmdDir: string): string;
11
+ /** Whether a config.vdf holds a cached login (a ConnectCache entry). */
12
+ export declare function hasCachedLogin(configVdf: string): boolean;
13
+ /** The account names a config.vdf knows (its Accounts block), in order. */
14
+ export declare function steamAccounts(configVdf: string): string[];
15
+ /** The account name kept beside SteamCMD (sbx-account.txt), or null. */
16
+ export declare function readSteamAccountFile(steamcmdDir: string): string | null;
17
+ /** The sentry files beside steamcmd.exe (the newest 4, in name order), each bounded. */
18
+ export declare function readSentries(steamcmdDir: string): {
19
+ name: string;
20
+ base64: string;
21
+ }[];
22
+ /**
23
+ * The cached login in a SteamCMD folder, or null: no config.vdf, no cached login in it, or no account name (`account`
24
+ * is used when the folder does not say one).
25
+ */
26
+ export declare function readSteamCmdLogin(steamcmdDir: string, account?: string): SteamPayload | null;
27
+ /** Writes a cached login into a SteamCMD folder (config\config.vdf, the sentries, the account name). */
28
+ export declare function writeSteamCmdLogin(steamcmdDir: string, p: SteamPayload): void;
@@ -0,0 +1,99 @@
1
+ // SteamCMD's cached login, for the host (a steamcmd folder on this PC) and the sandbox (C:\SteamCMD): config\config.vdf
2
+ // (its ConnectCache holds the login token) and the ssfn sentry files beside steamcmd.exe. No password is ever in them.
3
+ // Every file is read bounded and without following links: the sandbox may have written them.
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { readBoundedFile } from '../../io/bounded.js';
7
+ import { decodeText } from '../../io/text.js';
8
+ import { parseVdf, vdfObject } from '../../vdf.js';
9
+ import { SteamPayloadSchema } from '../payloads.js';
10
+ /** At most this much of config.vdf is read (the payload's limit). */
11
+ export const MAX_STEAM_CONFIG_BYTES = 256 * 1024;
12
+ /** A sentry's bytes (its base64 fits the payload's 64 KB). */
13
+ export const MAX_SENTRY_BYTES = 48 * 1024;
14
+ const MAX_SENTRIES = 4;
15
+ const MAX_ENTRIES = 5000;
16
+ const SENTRY = /^ssfn\d{1,40}$/;
17
+ export const STEAM_ACCOUNT = /^[A-Za-z0-9_]{1,64}$/;
18
+ /** The file SteamCMD's folder keeps the account name in (sbx-steam writes it; config.vdf may not say it). */
19
+ export const STEAM_ACCOUNT_FILE = 'sbx-account.txt';
20
+ export function steamConfigFile(steamcmdDir) {
21
+ return path.join(steamcmdDir, 'config', 'config.vdf');
22
+ }
23
+ function steamKey(root) {
24
+ return vdfObject(root, 'InstallConfigStore', 'Software', 'Valve', 'Steam');
25
+ }
26
+ /** Whether a config.vdf holds a cached login (a ConnectCache entry). */
27
+ export function hasCachedLogin(configVdf) {
28
+ const cache = vdfObject(steamKey(parseVdf(configVdf, { maxBytes: MAX_STEAM_CONFIG_BYTES })), 'ConnectCache');
29
+ return cache !== undefined && Object.keys(cache).length > 0;
30
+ }
31
+ /** The account names a config.vdf knows (its Accounts block), in order. */
32
+ export function steamAccounts(configVdf) {
33
+ const accounts = vdfObject(steamKey(parseVdf(configVdf, { maxBytes: MAX_STEAM_CONFIG_BYTES })), 'Accounts');
34
+ return accounts ? Object.keys(accounts).filter((a) => STEAM_ACCOUNT.test(a)) : [];
35
+ }
36
+ /** The account name kept beside SteamCMD (sbx-account.txt), or null. */
37
+ export function readSteamAccountFile(steamcmdDir) {
38
+ const bytes = readBoundedFile(path.join(steamcmdDir, 'config', STEAM_ACCOUNT_FILE), 256);
39
+ const name = bytes ? decodeText(bytes).text.trim() : '';
40
+ return STEAM_ACCOUNT.test(name) ? name : null;
41
+ }
42
+ /** The sentry files beside steamcmd.exe (the newest 4, in name order), each bounded. */
43
+ export function readSentries(steamcmdDir) {
44
+ let names;
45
+ try {
46
+ names = fs
47
+ .readdirSync(steamcmdDir)
48
+ .slice(0, MAX_ENTRIES)
49
+ .filter((n) => SENTRY.test(n));
50
+ }
51
+ catch {
52
+ return [];
53
+ }
54
+ const mtime = (name) => {
55
+ try {
56
+ return fs.lstatSync(path.join(steamcmdDir, name)).mtimeMs;
57
+ }
58
+ catch {
59
+ return 0;
60
+ }
61
+ };
62
+ const found = [];
63
+ for (const name of names.sort((a, b) => mtime(b) - mtime(a))) {
64
+ if (found.length >= MAX_SENTRIES)
65
+ break;
66
+ const bytes = readBoundedFile(path.join(steamcmdDir, name), MAX_SENTRY_BYTES);
67
+ if (bytes && bytes.length)
68
+ found.push({ name, base64: bytes.toString('base64') });
69
+ }
70
+ // By name: the same files read back the same (file times change when they are written in a sandbox).
71
+ return found.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
72
+ }
73
+ /**
74
+ * The cached login in a SteamCMD folder, or null: no config.vdf, no cached login in it, or no account name (`account`
75
+ * is used when the folder does not say one).
76
+ */
77
+ export function readSteamCmdLogin(steamcmdDir, account) {
78
+ const bytes = readBoundedFile(steamConfigFile(steamcmdDir), MAX_STEAM_CONFIG_BYTES);
79
+ if (!bytes)
80
+ return null;
81
+ const configVdf = decodeText(bytes).text;
82
+ if (!hasCachedLogin(configVdf))
83
+ return null;
84
+ const name = readSteamAccountFile(steamcmdDir) ?? steamAccounts(configVdf)[0] ?? account;
85
+ if (!name)
86
+ return null;
87
+ const parsed = SteamPayloadSchema.safeParse({ account: name, configVdf, sentries: readSentries(steamcmdDir) });
88
+ return parsed.success ? parsed.data : null;
89
+ }
90
+ /** Writes a cached login into a SteamCMD folder (config\config.vdf, the sentries, the account name). */
91
+ export function writeSteamCmdLogin(steamcmdDir, p) {
92
+ const login = SteamPayloadSchema.parse(p);
93
+ const config = path.dirname(steamConfigFile(steamcmdDir));
94
+ fs.mkdirSync(config, { recursive: true });
95
+ fs.writeFileSync(steamConfigFile(steamcmdDir), login.configVdf, 'utf8');
96
+ fs.writeFileSync(path.join(config, STEAM_ACCOUNT_FILE), login.account, 'utf8');
97
+ for (const s of login.sentries)
98
+ fs.writeFileSync(path.join(steamcmdDir, s.name), Buffer.from(s.base64, 'base64'));
99
+ }
@@ -0,0 +1,41 @@
1
+ export declare const SERVICE_KINDS: readonly ["epic", "steam", "unity", "cfx", "keystore", "play", "expo", "appstore"];
2
+ export type ServiceKind = (typeof SERVICE_KINDS)[number];
3
+ /** The toolchains a sign-in serves (it is handed over only when one of them is on for the boot). */
4
+ export type UsedBy = 'unreal' | 'steam' | 'unity' | 'fivem' | 'android' | 'flutter' | 'reactNative' | 'godot' | 'dotnet';
5
+ export declare const USED_BY: readonly UsedBy[];
6
+ /** Where a saved sign-in came from: this PC's program, a file you gave, values you typed, or a sandbox. */
7
+ export type AccountSource = 'pc' | 'file' | 'typed' | 'sandbox';
8
+ export declare const ACCOUNT_SOURCES: readonly AccountSource[];
9
+ /** One value `sandbox account login` asks for (or `import --from` needs besides the file). */
10
+ export interface ServiceField {
11
+ readonly name: string;
12
+ readonly label: string;
13
+ readonly secret: boolean;
14
+ readonly optional?: boolean;
15
+ readonly pattern?: RegExp;
16
+ }
17
+ export interface ServiceSpec<K extends ServiceKind = ServiceKind> {
18
+ readonly kind: K;
19
+ readonly label: string;
20
+ /** Handed over only when one of these is on for this boot. */
21
+ readonly usedBy: readonly UsedBy[];
22
+ readonly sources: readonly AccountSource[];
23
+ /** Works in one sandbox at a time (a lease on this PC). */
24
+ readonly singleHolder: boolean;
25
+ /** The sandbox may hand a renewed one back. */
26
+ readonly returns: boolean;
27
+ /** The largest payload (its JSON) accepted from a file or a sandbox. */
28
+ readonly maxBytes: number;
29
+ /** Shown on every surface. */
30
+ readonly warnings: readonly string[];
31
+ /** What `login` asks for, or what `import --from` needs besides the file. */
32
+ readonly fields: readonly ServiceField[];
33
+ }
34
+ export declare const SERVICE_SPECS: {
35
+ readonly [K in ServiceKind]: ServiceSpec<K>;
36
+ };
37
+ /** Where a sandbox leaves a renewed sign-in, under the data folder: state\accounts\<kind>.json. */
38
+ export declare const HANDOFF_PARTS: readonly ["state", "accounts"];
39
+ export declare function isServiceKind(value: string): value is ServiceKind;
40
+ /** Whether a sign-in is wanted when these toolchains are on. */
41
+ export declare function serviceWanted(kind: ServiceKind, on: ReadonlySet<UsedBy>): boolean;
@@ -0,0 +1,154 @@
1
+ // Service sign-ins a sandbox can keep (accounts.<kind>.share): what each one is, which toolchains use it, where it can
2
+ // come from, and the rules for handing it over (one sandbox at a time, handed back when renewed). Pure, web-safe: no
3
+ // Node built-ins. The payload shapes are in payloads.ts, the host side in host/accounts, the sandbox side in
4
+ // guest/accounts.
5
+ export const SERVICE_KINDS = ['epic', 'steam', 'unity', 'cfx', 'keystore', 'play', 'expo', 'appstore'];
6
+ export const USED_BY = [
7
+ 'unreal',
8
+ 'steam',
9
+ 'unity',
10
+ 'fivem',
11
+ 'android',
12
+ 'flutter',
13
+ 'reactNative',
14
+ 'godot',
15
+ 'dotnet',
16
+ ];
17
+ export const ACCOUNT_SOURCES = ['pc', 'file', 'typed', 'sandbox'];
18
+ const AGENT_CAN_USE = 'The agent in the sandbox can use this sign-in while it is there.';
19
+ const ONE_PLACE = 'It works in one sandbox at a time: a second sandbox starts without it while the first one runs.';
20
+ export const SERVICE_SPECS = {
21
+ epic: {
22
+ kind: 'epic',
23
+ label: 'Epic Games',
24
+ usedBy: ['unreal'],
25
+ sources: ['pc', 'sandbox'],
26
+ singleHolder: true,
27
+ returns: true,
28
+ maxBytes: 64 * 1024,
29
+ warnings: [
30
+ AGENT_CAN_USE,
31
+ "A sign-in works in one place at a time: taking this PC's signs the launcher on this PC out the first time a sandbox uses it.",
32
+ ],
33
+ fields: [],
34
+ },
35
+ steam: {
36
+ kind: 'steam',
37
+ label: 'Steam (SteamCMD)',
38
+ usedBy: ['steam'],
39
+ sources: ['file', 'sandbox'],
40
+ singleHolder: true,
41
+ returns: true,
42
+ maxBytes: 768 * 1024,
43
+ warnings: [
44
+ AGENT_CAN_USE + ' It can upload builds and workshop items to your Steam apps.',
45
+ ONE_PLACE,
46
+ 'No password is kept: sign in once with sbx-steam login in a sandbox (Steam Guard asks there).',
47
+ ],
48
+ fields: [],
49
+ },
50
+ unity: {
51
+ kind: 'unity',
52
+ label: 'Unity',
53
+ usedBy: ['unity'],
54
+ sources: ['pc', 'file', 'typed', 'sandbox'],
55
+ singleHolder: true,
56
+ returns: true,
57
+ maxBytes: 256 * 1024,
58
+ warnings: [
59
+ AGENT_CAN_USE,
60
+ ONE_PLACE,
61
+ 'A Pro seat is handed back when the sandbox stops cleanly; a sandbox closed abruptly may keep it until you return it.',
62
+ ],
63
+ fields: [
64
+ { name: 'email', label: 'Unity ID email', secret: false, optional: true },
65
+ { name: 'password', label: 'Unity ID password', secret: true, optional: true },
66
+ { name: 'serial', label: 'Serial (Plus or Pro; empty for Personal)', secret: true, optional: true },
67
+ ],
68
+ },
69
+ cfx: {
70
+ kind: 'cfx',
71
+ label: 'Cfx.re (FiveM / RedM server key)',
72
+ usedBy: ['fivem'],
73
+ sources: ['typed'],
74
+ singleHolder: false,
75
+ returns: false,
76
+ maxBytes: 4 * 1024,
77
+ warnings: [AGENT_CAN_USE + ' Anyone with the key can run a server under your Cfx.re account.'],
78
+ fields: [
79
+ { name: 'licenseKey', label: 'Server licence key (cfxk_...)', secret: true, pattern: /^cfxk_[A-Za-z0-9_]+$/ },
80
+ {
81
+ name: 'steamWebApiKey',
82
+ label: 'Steam Web API key (optional)',
83
+ secret: true,
84
+ optional: true,
85
+ pattern: /^[A-F0-9]{32}$/,
86
+ },
87
+ ],
88
+ },
89
+ keystore: {
90
+ kind: 'keystore',
91
+ label: 'Android upload keystore',
92
+ usedBy: ['android'],
93
+ sources: ['file'],
94
+ singleHolder: false,
95
+ returns: false,
96
+ maxBytes: 512 * 1024,
97
+ warnings: [AGENT_CAN_USE + ' It can sign app updates as you; keep a backup of the keystore elsewhere.'],
98
+ fields: [
99
+ { name: 'storePassword', label: 'Keystore password', secret: true },
100
+ { name: 'keyAlias', label: 'Key alias', secret: false },
101
+ { name: 'keyPassword', label: 'Key password', secret: true },
102
+ ],
103
+ },
104
+ play: {
105
+ kind: 'play',
106
+ label: 'Google Play (service account)',
107
+ usedBy: ['android'],
108
+ sources: ['file'],
109
+ singleHolder: false,
110
+ returns: false,
111
+ maxBytes: 128 * 1024,
112
+ warnings: [AGENT_CAN_USE + ' It can publish to Google Play with what the service account is allowed.'],
113
+ fields: [],
114
+ },
115
+ expo: {
116
+ kind: 'expo',
117
+ label: 'Expo (EAS)',
118
+ usedBy: ['reactNative'],
119
+ sources: ['typed'],
120
+ singleHolder: false,
121
+ returns: false,
122
+ maxBytes: 4 * 1024,
123
+ warnings: [AGENT_CAN_USE + ' It can start EAS builds and submissions on your Expo account.'],
124
+ fields: [{ name: 'token', label: 'Expo access token', secret: true }],
125
+ },
126
+ appstore: {
127
+ kind: 'appstore',
128
+ label: 'App Store Connect API key',
129
+ usedBy: ['reactNative', 'flutter'],
130
+ sources: ['file', 'typed'],
131
+ singleHolder: false,
132
+ returns: false,
133
+ maxBytes: 16 * 1024,
134
+ warnings: [AGENT_CAN_USE + ' It can upload and submit apps with what the key is allowed.'],
135
+ fields: [
136
+ { name: 'issuerId', label: 'Issuer ID', secret: false },
137
+ { name: 'keyId', label: 'Key ID', secret: false, pattern: /^[A-Z0-9]{10}$/ },
138
+ ],
139
+ },
140
+ };
141
+ /** Where a sandbox leaves a renewed sign-in, under the data folder: state\accounts\<kind>.json. */
142
+ export const HANDOFF_PARTS = ['state', 'accounts'];
143
+ /** The toolchains that build for Android and so want its signing keys (they turn the Android toolchain on). */
144
+ const ANDROID_USERS = ['flutter', 'reactNative', 'godot', 'unity'];
145
+ export function isServiceKind(value) {
146
+ return SERVICE_KINDS.includes(value);
147
+ }
148
+ /** Whether a sign-in is wanted when these toolchains are on. */
149
+ export function serviceWanted(kind, on) {
150
+ const spec = SERVICE_SPECS[kind];
151
+ if (spec.usedBy.some((u) => on.has(u)))
152
+ return true;
153
+ return spec.usedBy.includes('android') && ANDROID_USERS.some((u) => on.has(u));
154
+ }
@@ -0,0 +1,151 @@
1
+ import { z } from 'zod';
2
+ import { type ServiceKind } from './kinds.js';
3
+ /** The Epic Games Launcher's "Remember me" (the Data value of [RememberMe] in its GameUserSettings.ini). */
4
+ export declare const EpicPayloadSchema: z.ZodObject<{
5
+ data: z.ZodString;
6
+ }, z.core.$strict>;
7
+ /** SteamCMD's cached login: config\config.vdf (ConnectCache) and the ssfn sentry files. No password. */
8
+ export declare const SteamPayloadSchema: z.ZodObject<{
9
+ account: z.ZodString;
10
+ configVdf: z.ZodString;
11
+ sentries: z.ZodArray<z.ZodObject<{
12
+ name: z.ZodString;
13
+ base64: z.ZodString;
14
+ }, z.core.$strict>>;
15
+ client: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strict>;
17
+ /** A Unity licence file (Unity_lic.ulf), and the Unity ID to sign in with when it has to be made again. */
18
+ export declare const UnityPayloadSchema: z.ZodObject<{
19
+ ulf: z.ZodOptional<z.ZodString>;
20
+ email: z.ZodOptional<z.ZodString>;
21
+ password: z.ZodOptional<z.ZodString>;
22
+ serial: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strict>;
24
+ /** A FiveM / RedM server licence key from the Cfx.re keymaster, and an optional Steam Web API key. */
25
+ export declare const CfxPayloadSchema: z.ZodObject<{
26
+ licenseKey: z.ZodString;
27
+ steamWebApiKey: z.ZodOptional<z.ZodString>;
28
+ }, z.core.$strict>;
29
+ /** An Android upload keystore and what opens it. */
30
+ export declare const KeystorePayloadSchema: z.ZodObject<{
31
+ fileName: z.ZodString;
32
+ jksBase64: z.ZodString;
33
+ storePassword: z.ZodString;
34
+ keyAlias: z.ZodString;
35
+ keyPassword: z.ZodString;
36
+ }, z.core.$strict>;
37
+ /** A Google Play service account key (its JSON file). */
38
+ export declare const PlayPayloadSchema: z.ZodObject<{
39
+ serviceAccountJson: z.ZodString;
40
+ }, z.core.$strict>;
41
+ /** An Expo access token (EXPO_TOKEN). */
42
+ export declare const ExpoPayloadSchema: z.ZodObject<{
43
+ token: z.ZodString;
44
+ }, z.core.$strict>;
45
+ /** An App Store Connect API key: its issuer, its ID and the .p8 private key. */
46
+ export declare const AppstorePayloadSchema: z.ZodObject<{
47
+ issuerId: z.ZodString;
48
+ keyId: z.ZodString;
49
+ p8: z.ZodString;
50
+ }, z.core.$strict>;
51
+ export declare const PAYLOADS: {
52
+ readonly epic: z.ZodObject<{
53
+ data: z.ZodString;
54
+ }, z.core.$strict>;
55
+ readonly steam: z.ZodObject<{
56
+ account: z.ZodString;
57
+ configVdf: z.ZodString;
58
+ sentries: z.ZodArray<z.ZodObject<{
59
+ name: z.ZodString;
60
+ base64: z.ZodString;
61
+ }, z.core.$strict>>;
62
+ client: z.ZodOptional<z.ZodString>;
63
+ }, z.core.$strict>;
64
+ readonly unity: z.ZodObject<{
65
+ ulf: z.ZodOptional<z.ZodString>;
66
+ email: z.ZodOptional<z.ZodString>;
67
+ password: z.ZodOptional<z.ZodString>;
68
+ serial: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strict>;
70
+ readonly cfx: z.ZodObject<{
71
+ licenseKey: z.ZodString;
72
+ steamWebApiKey: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strict>;
74
+ readonly keystore: z.ZodObject<{
75
+ fileName: z.ZodString;
76
+ jksBase64: z.ZodString;
77
+ storePassword: z.ZodString;
78
+ keyAlias: z.ZodString;
79
+ keyPassword: z.ZodString;
80
+ }, z.core.$strict>;
81
+ readonly play: z.ZodObject<{
82
+ serviceAccountJson: z.ZodString;
83
+ }, z.core.$strict>;
84
+ readonly expo: z.ZodObject<{
85
+ token: z.ZodString;
86
+ }, z.core.$strict>;
87
+ readonly appstore: z.ZodObject<{
88
+ issuerId: z.ZodString;
89
+ keyId: z.ZodString;
90
+ p8: z.ZodString;
91
+ }, z.core.$strict>;
92
+ };
93
+ export type Payload<K extends ServiceKind> = z.output<(typeof PAYLOADS)[K]>;
94
+ export type AnyPayload = Payload<ServiceKind>;
95
+ export type Payloads = Partial<{
96
+ [K in ServiceKind]: Payload<K>;
97
+ }>;
98
+ /** The secrets-file field: the sign-ins this launch hands over, each optional. */
99
+ export declare const ServiceAccountsSchema: z.ZodObject<{
100
+ epic: z.ZodOptional<z.ZodObject<{
101
+ data: z.ZodString;
102
+ }, z.core.$strict>>;
103
+ steam: z.ZodOptional<z.ZodObject<{
104
+ account: z.ZodString;
105
+ configVdf: z.ZodString;
106
+ sentries: z.ZodArray<z.ZodObject<{
107
+ name: z.ZodString;
108
+ base64: z.ZodString;
109
+ }, z.core.$strict>>;
110
+ client: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strict>>;
112
+ unity: z.ZodOptional<z.ZodObject<{
113
+ ulf: z.ZodOptional<z.ZodString>;
114
+ email: z.ZodOptional<z.ZodString>;
115
+ password: z.ZodOptional<z.ZodString>;
116
+ serial: z.ZodOptional<z.ZodString>;
117
+ }, z.core.$strict>>;
118
+ cfx: z.ZodOptional<z.ZodObject<{
119
+ licenseKey: z.ZodString;
120
+ steamWebApiKey: z.ZodOptional<z.ZodString>;
121
+ }, z.core.$strict>>;
122
+ keystore: z.ZodOptional<z.ZodObject<{
123
+ fileName: z.ZodString;
124
+ jksBase64: z.ZodString;
125
+ storePassword: z.ZodString;
126
+ keyAlias: z.ZodString;
127
+ keyPassword: z.ZodString;
128
+ }, z.core.$strict>>;
129
+ play: z.ZodOptional<z.ZodObject<{
130
+ serviceAccountJson: z.ZodString;
131
+ }, z.core.$strict>>;
132
+ expo: z.ZodOptional<z.ZodObject<{
133
+ token: z.ZodString;
134
+ }, z.core.$strict>>;
135
+ appstore: z.ZodOptional<z.ZodObject<{
136
+ issuerId: z.ZodString;
137
+ keyId: z.ZodString;
138
+ p8: z.ZodString;
139
+ }, z.core.$strict>>;
140
+ }, z.core.$strict>;
141
+ export type ServiceAccounts = z.output<typeof ServiceAccountsSchema>;
142
+ /** A launch's id (generate.ts: "<ms>-<6 hex>"). */
143
+ export declare const LaunchIdSchema: z.ZodString;
144
+ /** What a sandbox leaves in state\accounts\<kind>.json: the renewed sign-in and the launch it belongs to. */
145
+ export declare function handoffSchema<K extends ServiceKind>(kind: K): z.ZodType<{
146
+ kind: K;
147
+ launchId: string;
148
+ payload: Payload<K>;
149
+ }>;
150
+ /** The kinds that are in a secrets-file field, in order. */
151
+ export declare function deliveredKinds(given: ServiceAccounts | undefined): ServiceKind[];