windows-development-sandbox 1.5.0 → 1.7.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 (448) hide show
  1. package/README.md +1 -0
  2. package/config.example.json +17 -1
  3. package/dist/cli/args.d.ts +13 -2
  4. package/dist/cli/args.js +95 -24
  5. package/dist/cli/commands/accounts.js +45 -17
  6. package/dist/cli/commands/context.d.ts +2 -0
  7. package/dist/cli/commands/context.js +9 -2
  8. package/dist/cli/commands/data/clean.js +32 -9
  9. package/dist/cli/commands/index.d.ts +1 -0
  10. package/dist/cli/commands/index.js +1 -0
  11. package/dist/cli/commands/launch/add-root.d.ts +3 -2
  12. package/dist/cli/commands/launch/add-root.js +11 -10
  13. package/dist/cli/commands/launch/launch.js +57 -4
  14. package/dist/cli/commands/launch/prepare.js +3 -1
  15. package/dist/cli/commands/maintenance/audit.js +1 -1
  16. package/dist/cli/commands/maintenance/clean.d.ts +1 -1
  17. package/dist/cli/commands/maintenance/clean.js +17 -3
  18. package/dist/cli/commands/maintenance/config.d.ts +1 -1
  19. package/dist/cli/commands/maintenance/config.js +112 -10
  20. package/dist/cli/commands/maintenance/doctor.d.ts +1 -1
  21. package/dist/cli/commands/maintenance/doctor.js +2 -4
  22. package/dist/cli/commands/maintenance/migrate.d.ts +2 -1
  23. package/dist/cli/commands/maintenance/migrate.js +19 -4
  24. package/dist/cli/commands/maintenance/sync.js +2 -0
  25. package/dist/cli/commands/maintenance/update.d.ts +2 -0
  26. package/dist/cli/commands/maintenance/update.js +27 -4
  27. package/dist/cli/commands/projects/here.js +12 -7
  28. package/dist/cli/commands/projects/projects.js +26 -17
  29. package/dist/cli/commands/registry.js +7 -0
  30. package/dist/cli/commands/repair/checks/agents.d.ts +2 -0
  31. package/dist/cli/commands/repair/checks/agents.js +70 -0
  32. package/dist/cli/commands/repair/checks/common.d.ts +8 -0
  33. package/dist/cli/commands/repair/checks/common.js +22 -0
  34. package/dist/cli/commands/repair/checks/data.d.ts +2 -0
  35. package/dist/cli/commands/repair/checks/data.js +241 -0
  36. package/dist/cli/commands/repair/checks/index.d.ts +2 -0
  37. package/dist/cli/commands/repair/checks/index.js +20 -0
  38. package/dist/cli/commands/repair/checks/install.d.ts +5 -0
  39. package/dist/cli/commands/repair/checks/install.js +318 -0
  40. package/dist/cli/commands/repair/checks/machine.d.ts +2 -0
  41. package/dist/cli/commands/repair/checks/machine.js +232 -0
  42. package/dist/cli/commands/repair/checks/network.d.ts +6 -0
  43. package/dist/cli/commands/repair/checks/network.js +60 -0
  44. package/dist/cli/commands/repair/checks/pc.d.ts +4 -0
  45. package/dist/cli/commands/repair/checks/pc.js +55 -0
  46. package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
  47. package/dist/cli/commands/repair/checks/sandbox.js +267 -0
  48. package/dist/cli/commands/repair/checks/settings.d.ts +2 -0
  49. package/dist/cli/commands/repair/checks/settings.js +169 -0
  50. package/dist/cli/commands/repair/checks/vpn.d.ts +2 -0
  51. package/dist/cli/commands/repair/checks/vpn.js +53 -0
  52. package/dist/cli/commands/repair/engine.d.ts +32 -0
  53. package/dist/cli/commands/repair/engine.js +127 -0
  54. package/dist/cli/commands/repair/env.d.ts +7 -0
  55. package/dist/cli/commands/repair/env.js +49 -0
  56. package/dist/cli/commands/repair/index.d.ts +1 -9
  57. package/dist/cli/commands/repair/index.js +2 -54
  58. package/dist/cli/commands/repair/log.d.ts +17 -0
  59. package/dist/cli/commands/repair/log.js +82 -0
  60. package/dist/cli/commands/repair/printer.d.ts +32 -0
  61. package/dist/cli/commands/repair/printer.js +132 -0
  62. package/dist/cli/commands/repair/run.d.ts +33 -0
  63. package/dist/cli/commands/repair/run.js +133 -0
  64. package/dist/cli/commands/repair/types.d.ts +97 -9
  65. package/dist/cli/commands/repair/types.js +11 -7
  66. package/dist/cli/commands/resume.js +2 -2
  67. package/dist/cli/commands/sessions/list.js +5 -2
  68. package/dist/cli/commands/sessions/status.d.ts +2 -0
  69. package/dist/cli/commands/sessions/status.js +27 -6
  70. package/dist/cli/commands/setup/index.d.ts +5 -0
  71. package/dist/cli/commands/setup/index.js +25 -1
  72. package/dist/cli/commands/storage/index.d.ts +2 -0
  73. package/dist/cli/commands/storage/index.js +2 -0
  74. package/dist/cli/commands/storage/offer.d.ts +3 -0
  75. package/dist/cli/commands/storage/offer.js +85 -0
  76. package/dist/cli/commands/storage/storage.d.ts +8 -0
  77. package/dist/cli/commands/storage/storage.js +171 -0
  78. package/dist/cli/commands/user-config.js +1 -1
  79. package/dist/cli/commands/vpn.d.ts +4 -0
  80. package/dist/cli/commands/vpn.js +75 -0
  81. package/dist/cli/commands/web.d.ts +4 -0
  82. package/dist/cli/commands/web.js +95 -0
  83. package/dist/cli/history.js +1 -1
  84. package/dist/cli/index.js +46 -3
  85. package/dist/cli/manifest.d.ts +303 -29
  86. package/dist/cli/manifest.js +173 -43
  87. package/dist/cli/menu/add-agent.d.ts +47 -0
  88. package/dist/cli/menu/add-agent.js +168 -0
  89. package/dist/cli/menu/apps.d.ts +31 -2
  90. package/dist/cli/menu/apps.js +44 -5
  91. package/dist/cli/menu/command-fields.d.ts +18 -0
  92. package/dist/cli/menu/command-fields.js +61 -0
  93. package/dist/cli/menu/command-form.d.ts +22 -0
  94. package/dist/cli/menu/command-form.js +169 -46
  95. package/dist/cli/menu/data-folder.d.ts +18 -0
  96. package/dist/cli/menu/data-folder.js +99 -0
  97. package/dist/cli/menu/menu.d.ts +1 -1
  98. package/dist/cli/menu/menu.js +11 -8
  99. package/dist/cli/menu/pages/accounts-page.js +55 -24
  100. package/dist/cli/menu/pages/agents-page.d.ts +66 -0
  101. package/dist/cli/menu/pages/agents-page.js +338 -0
  102. package/dist/cli/menu/pages/apps-page.js +1 -2
  103. package/dist/cli/menu/pages/list-page.d.ts +16 -3
  104. package/dist/cli/menu/pages/list-page.js +40 -8
  105. package/dist/cli/menu/pages/maintenance-page.d.ts +9 -0
  106. package/dist/cli/menu/pages/maintenance-page.js +161 -72
  107. package/dist/cli/menu/pages/sandbox-page.d.ts +3 -0
  108. package/dist/cli/menu/pages/sandbox-page.js +132 -43
  109. package/dist/cli/menu/pages/sessions-page.d.ts +4 -0
  110. package/dist/cli/menu/pages/sessions-page.js +41 -25
  111. package/dist/cli/menu/pages/settings-page.d.ts +8 -4
  112. package/dist/cli/menu/pages/settings-page.js +36 -13
  113. package/dist/cli/menu/settings/categories.d.ts +2 -0
  114. package/dist/cli/menu/settings/categories.js +19 -44
  115. package/dist/cli/menu/settings/collections/collection-editor.d.ts +7 -1
  116. package/dist/cli/menu/settings/collections/collection-editor.js +12 -8
  117. package/dist/cli/menu/settings/collections/map-editor.js +5 -1
  118. package/dist/cli/menu/settings/collections/object-list-editor.js +2 -2
  119. package/dist/cli/menu/settings/collections/object-map-editor.js +2 -2
  120. package/dist/cli/menu/settings/collections/string-list-editor.d.ts +11 -1
  121. package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
  122. package/dist/cli/menu/settings/index.d.ts +1 -1
  123. package/dist/cli/menu/settings/index.js +1 -1
  124. package/dist/cli/menu/settings/object-editor.d.ts +5 -1
  125. package/dist/cli/menu/settings/object-editor.js +15 -4
  126. package/dist/cli/menu/settings/path-kind.d.ts +20 -0
  127. package/dist/cli/menu/settings/path-kind.js +44 -0
  128. package/dist/cli/menu/settings/schema-node.d.ts +9 -0
  129. package/dist/cli/menu/settings/schema-node.js +26 -0
  130. package/dist/cli/menu/settings/value-editor.d.ts +5 -0
  131. package/dist/cli/menu/settings/value-editor.js +51 -18
  132. package/dist/cli/menu/several.js +7 -5
  133. package/dist/cli/menu/shell.d.ts +37 -10
  134. package/dist/cli/menu/shell.js +90 -10
  135. package/dist/cli/menu/vpn-login.d.ts +16 -0
  136. package/dist/cli/menu/vpn-login.js +66 -0
  137. package/dist/cli/output/print.d.ts +2 -0
  138. package/dist/cli/output/print.js +8 -1
  139. package/dist/cli/services/accounts-service.d.ts +2 -0
  140. package/dist/cli/services/accounts-service.js +2 -2
  141. package/dist/cli/services/health-service.d.ts +0 -6
  142. package/dist/cli/services/health-service.js +5 -42
  143. package/dist/cli/services/index.d.ts +3 -1
  144. package/dist/cli/services/index.js +3 -1
  145. package/dist/cli/services/migrate-service.js +1 -1
  146. package/dist/cli/services/update-service.d.ts +2 -0
  147. package/dist/cli/services/update-service.js +13 -6
  148. package/dist/cli/services/vpn-service.d.ts +28 -0
  149. package/dist/cli/services/vpn-service.js +46 -0
  150. package/dist/cli/services/web-service.d.ts +22 -0
  151. package/dist/cli/services/web-service.js +111 -0
  152. package/dist/cli/tui/app.d.ts +6 -3
  153. package/dist/cli/tui/app.js +12 -5
  154. package/dist/cli/tui/dialogs/path-listing.d.ts +43 -0
  155. package/dist/cli/tui/dialogs/path-listing.js +127 -0
  156. package/dist/cli/tui/dialogs/path-picker.d.ts +67 -0
  157. package/dist/cli/tui/dialogs/path-picker.js +423 -0
  158. package/dist/cli/tui/dialogs/text-screen.d.ts +6 -0
  159. package/dist/cli/tui/dialogs/text-screen.js +10 -3
  160. package/dist/cli/tui/frame.d.ts +7 -10
  161. package/dist/cli/tui/frame.js +19 -10
  162. package/dist/cli/tui/index.d.ts +4 -3
  163. package/dist/cli/tui/index.js +2 -1
  164. package/dist/cli/tui/list/list-screen.d.ts +14 -2
  165. package/dist/cli/tui/list/list-screen.js +68 -32
  166. package/dist/cli/tui/list/list-types.d.ts +8 -4
  167. package/dist/cli/tui/nav.d.ts +29 -0
  168. package/dist/cli/tui/nav.js +67 -0
  169. package/dist/cli/validate.d.ts +1 -1
  170. package/dist/cli/validate.js +3 -3
  171. package/dist/cli/version.d.ts +2 -0
  172. package/dist/cli/version.js +11 -0
  173. package/dist/core/config/defaults.js +5 -1
  174. package/dist/core/config/loader.js +12 -2
  175. package/dist/core/local-config/overrides.js +1 -0
  176. package/dist/core/prompt.d.ts +19 -0
  177. package/dist/core/prompt.js +43 -3
  178. package/dist/core/schema/common.d.ts +6 -0
  179. package/dist/core/schema/common.js +8 -0
  180. package/dist/core/schema/config.d.ts +23 -0
  181. package/dist/core/schema/config.js +10 -1
  182. package/dist/core/schema/harness.d.ts +1 -0
  183. package/dist/core/schema/harness.js +8 -2
  184. package/dist/core/schema/index.d.ts +3 -1
  185. package/dist/core/schema/index.js +3 -1
  186. package/dist/core/schema/profile.d.ts +1 -0
  187. package/dist/core/schema/profile.js +3 -0
  188. package/dist/core/schema/redact.d.ts +13 -0
  189. package/dist/core/schema/redact.js +75 -0
  190. package/dist/core/schema/sandbox.js +1 -0
  191. package/dist/core/schema/vpn.d.ts +17 -0
  192. package/dist/core/schema/vpn.js +22 -0
  193. package/dist/core/schema/web.d.ts +6 -0
  194. package/dist/core/schema/web.js +14 -0
  195. package/dist/core/types.d.ts +26 -0
  196. package/dist/guest/agents/agent-files.d.ts +49 -0
  197. package/dist/guest/agents/agent-files.js +63 -0
  198. package/dist/guest/agents/agent-installer.js +2 -9
  199. package/dist/guest/agents/local-state.d.ts +12 -0
  200. package/dist/guest/agents/local-state.js +198 -0
  201. package/dist/guest/agents/sbx-agent.d.ts +2 -0
  202. package/dist/guest/agents/sbx-agent.js +35 -0
  203. package/dist/guest/boot/boot.d.ts +4 -0
  204. package/dist/guest/boot/boot.js +50 -11
  205. package/dist/guest/daemon/daemon.js +4 -1
  206. package/dist/guest/daemon/exec.js +2 -1
  207. package/dist/guest/daemon/idle-shutdown.js +2 -0
  208. package/dist/guest/daemon/sessions.js +4 -1
  209. package/dist/guest/entries/agent.d.ts +1 -0
  210. package/dist/guest/entries/agent.js +10 -0
  211. package/dist/guest/entries/daemon.js +2 -0
  212. package/dist/guest/runtime/csc.d.ts +1 -0
  213. package/dist/guest/runtime/csc.js +1 -0
  214. package/dist/guest/runtime/secrets.d.ts +12 -0
  215. package/dist/guest/runtime/secrets.js +63 -0
  216. package/dist/guest/setup/claude-profile.d.ts +2 -1
  217. package/dist/guest/setup/claude-profile.js +12 -1
  218. package/dist/guest/setup/environment.d.ts +6 -0
  219. package/dist/guest/setup/environment.js +56 -6
  220. package/dist/guest/setup/path-plan.d.ts +32 -0
  221. package/dist/guest/setup/path-plan.js +67 -0
  222. package/dist/guest/setup/shell-path.d.ts +1 -0
  223. package/dist/guest/setup/shell-path.js +22 -0
  224. package/dist/guest/toolchains/languages/python.js +1 -1
  225. package/dist/guest/toolchains/runtimes.js +2 -2
  226. package/dist/guest/vpn/index.d.ts +1 -0
  227. package/dist/guest/vpn/index.js +1 -0
  228. package/dist/guest/vpn/openvpn.d.ts +9 -0
  229. package/dist/guest/vpn/openvpn.js +47 -0
  230. package/dist/guest/vpn/tunnel.d.ts +17 -0
  231. package/dist/guest/vpn/tunnel.js +78 -0
  232. package/dist/guest/vpn/vpn.d.ts +6 -0
  233. package/dist/guest/vpn/vpn.js +126 -0
  234. package/dist/host/channel/attach.d.ts +3 -1
  235. package/dist/host/channel/attach.js +1 -1
  236. package/dist/host/channel/channel.d.ts +7 -0
  237. package/dist/host/channel/channel.js +26 -2
  238. package/dist/host/health/acl-read.d.ts +17 -0
  239. package/dist/host/health/acl-read.js +45 -0
  240. package/dist/host/health/config-backup.d.ts +11 -0
  241. package/dist/host/health/config-backup.js +73 -0
  242. package/dist/host/health/index.d.ts +6 -0
  243. package/dist/host/health/index.js +7 -0
  244. package/dist/host/health/install-state.d.ts +33 -0
  245. package/dist/host/health/install-state.js +110 -0
  246. package/dist/host/health/path-copies.d.ts +32 -0
  247. package/dist/host/health/path-copies.js +82 -0
  248. package/dist/host/health/stale.d.ts +45 -0
  249. package/dist/host/health/stale.js +120 -0
  250. package/dist/host/health/system.d.ts +37 -0
  251. package/dist/host/health/system.js +87 -0
  252. package/dist/host/install/copies.d.ts +13 -0
  253. package/dist/host/install/copies.js +63 -0
  254. package/dist/host/install/index.d.ts +1 -0
  255. package/dist/host/install/index.js +1 -0
  256. package/dist/host/launch/generate.js +25 -1
  257. package/dist/host/launch/session-file.js +4 -1
  258. package/dist/host/launch/stage.js +1 -1
  259. package/dist/host/migrate/backup.js +3 -0
  260. package/dist/host/migrate/migrations/config-file.d.ts +2 -0
  261. package/dist/host/migrate/migrations/config-file.js +7 -0
  262. package/dist/host/migrate/migrations/follow-machine-storage.js +9 -1
  263. package/dist/host/migrate/migrations/pin-storage-root.d.ts +4 -0
  264. package/dist/host/migrate/migrations/pin-storage-root.js +46 -0
  265. package/dist/host/migrate/migrations/unpin-config-defaults.js +4 -1
  266. package/dist/host/migrate/registry.js +2 -1
  267. package/dist/host/profile/accounts.d.ts +25 -1
  268. package/dist/host/profile/accounts.js +96 -13
  269. package/dist/host/profile/agent-accounts.d.ts +5 -1
  270. package/dist/host/profile/agent-accounts.js +35 -5
  271. package/dist/host/profile/index.d.ts +2 -1
  272. package/dist/host/profile/index.js +1 -0
  273. package/dist/host/profile/plugin-share.d.ts +26 -0
  274. package/dist/host/profile/plugin-share.js +146 -0
  275. package/dist/host/projects/join.d.ts +7 -1
  276. package/dist/host/projects/join.js +21 -4
  277. package/dist/host/projects/registry.d.ts +16 -10
  278. package/dist/host/projects/registry.js +74 -6
  279. package/dist/host/sandbox/platform.d.ts +2 -0
  280. package/dist/host/sandbox/platform.js +21 -2
  281. package/dist/host/secrets/index.d.ts +2 -0
  282. package/dist/host/secrets/index.js +2 -0
  283. package/dist/host/secrets/launch-secrets.d.ts +17 -0
  284. package/dist/host/secrets/launch-secrets.js +93 -0
  285. package/dist/host/secrets/secret-store.d.ts +25 -0
  286. package/dist/host/secrets/secret-store.js +89 -0
  287. package/dist/host/sharing/acl.d.ts +16 -2
  288. package/dist/host/sharing/acl.js +35 -10
  289. package/dist/host/sharing/current.js +11 -2
  290. package/dist/host/sharing/doctor.d.ts +2 -0
  291. package/dist/host/sharing/doctor.js +44 -0
  292. package/dist/host/sharing/group-access.d.ts +6 -0
  293. package/dist/host/sharing/group-access.js +24 -0
  294. package/dist/host/sharing/index.d.ts +2 -1
  295. package/dist/host/sharing/index.js +2 -1
  296. package/dist/host/sharing/lifecycle.d.ts +8 -2
  297. package/dist/host/sharing/lifecycle.js +16 -7
  298. package/dist/host/storage/cleanup.d.ts +2 -0
  299. package/dist/host/storage/cleanup.js +2 -1
  300. package/dist/host/storage/history.d.ts +21 -0
  301. package/dist/host/storage/history.js +49 -0
  302. package/dist/host/storage/index.d.ts +4 -0
  303. package/dist/host/storage/index.js +4 -0
  304. package/dist/host/storage/move.d.ts +95 -0
  305. package/dist/host/storage/move.js +384 -0
  306. package/dist/host/storage/offer.d.ts +11 -0
  307. package/dist/host/storage/offer.js +36 -0
  308. package/dist/host/storage/root.d.ts +18 -0
  309. package/dist/host/storage/root.js +77 -0
  310. package/dist/host/tools/windows-terminal.d.ts +2 -0
  311. package/dist/host/tools/windows-terminal.js +23 -5
  312. package/dist/host/update/index.d.ts +1 -1
  313. package/dist/host/update/index.js +1 -1
  314. package/dist/host/update/notice.d.ts +2 -0
  315. package/dist/host/update/notice.js +13 -1
  316. package/dist/host/update/update-state.d.ts +6 -0
  317. package/dist/host/update/update-state.js +2 -0
  318. package/dist/host/update/updater.d.ts +19 -0
  319. package/dist/host/update/updater.js +88 -12
  320. package/dist/host/vpn/index.d.ts +4 -0
  321. package/dist/host/vpn/index.js +4 -0
  322. package/dist/host/vpn/login.d.ts +24 -0
  323. package/dist/host/vpn/login.js +79 -0
  324. package/dist/host/vpn/nordvpn.d.ts +21 -0
  325. package/dist/host/vpn/nordvpn.js +77 -0
  326. package/dist/host/vpn/prepare.d.ts +17 -0
  327. package/dist/host/vpn/prepare.js +77 -0
  328. package/dist/host/vpn/status.d.ts +12 -0
  329. package/dist/host/vpn/status.js +53 -0
  330. package/dist/host/web/auth.d.ts +38 -0
  331. package/dist/host/web/auth.js +96 -0
  332. package/dist/host/web/backend.d.ts +14 -0
  333. package/dist/host/web/backend.js +1 -0
  334. package/dist/host/web/bridge.d.ts +27 -0
  335. package/dist/host/web/bridge.js +144 -0
  336. package/dist/host/web/browser.d.ts +1 -0
  337. package/dist/host/web/browser.js +10 -0
  338. package/dist/host/web/control.d.ts +17 -0
  339. package/dist/host/web/control.js +67 -0
  340. package/dist/host/web/index.d.ts +9 -0
  341. package/dist/host/web/index.js +8 -0
  342. package/dist/host/web/runner.d.ts +14 -0
  343. package/dist/host/web/runner.js +45 -0
  344. package/dist/host/web/server.d.ts +40 -0
  345. package/dist/host/web/server.js +218 -0
  346. package/dist/host/web/state.d.ts +20 -0
  347. package/dist/host/web/state.js +41 -0
  348. package/dist/host/web/static-files.d.ts +13 -0
  349. package/dist/host/web/static-files.js +57 -0
  350. package/dist/runtime/agent.js +27614 -0
  351. package/dist/runtime/daemon.js +1012 -618
  352. package/dist/runtime/db.js +236 -106
  353. package/dist/runtime/main.js +1093 -250
  354. package/dist/runtime/netproxy.js +102 -3
  355. package/dist/runtime/view.js +102 -3
  356. package/dist/selftest/accounts.test.js +40 -0
  357. package/dist/selftest/agent-paths.test.d.ts +2 -0
  358. package/dist/selftest/agent-paths.test.js +115 -0
  359. package/dist/selftest/channel.test.js +5 -0
  360. package/dist/selftest/cli.test.js +34 -4
  361. package/dist/selftest/credentials.test.d.ts +2 -0
  362. package/dist/selftest/credentials.test.js +198 -0
  363. package/dist/selftest/generate.test.js +1 -1
  364. package/dist/selftest/health.test.d.ts +2 -0
  365. package/dist/selftest/health.test.js +470 -0
  366. package/dist/selftest/host-sim.test.js +2 -0
  367. package/dist/selftest/index.js +19 -0
  368. package/dist/selftest/layout.test.js +2 -0
  369. package/dist/selftest/menu-screens.d.ts +7 -0
  370. package/dist/selftest/menu-screens.js +65 -16
  371. package/dist/selftest/menu.test.js +574 -21
  372. package/dist/selftest/migrate.test.js +1 -1
  373. package/dist/selftest/personalization.test.js +3 -1
  374. package/dist/selftest/projects.test.js +39 -1
  375. package/dist/selftest/shared-use.test.js +64 -2
  376. package/dist/selftest/sharing.test.js +50 -1
  377. package/dist/selftest/storage.test.d.ts +2 -0
  378. package/dist/selftest/storage.test.js +363 -0
  379. package/dist/selftest/support/fixtures.d.ts +14 -0
  380. package/dist/selftest/support/releases.js +1 -1
  381. package/dist/selftest/toolchains.test.js +21 -0
  382. package/dist/selftest/update-service.test.js +87 -3
  383. package/dist/selftest/vpn.test.d.ts +2 -0
  384. package/dist/selftest/vpn.test.js +279 -0
  385. package/dist/selftest/web.test.d.ts +2 -0
  386. package/dist/selftest/web.test.js +304 -0
  387. package/dist/shared/apps/catalogue.js +31 -0
  388. package/dist/shared/channel/index.d.ts +1 -0
  389. package/dist/shared/channel/index.js +1 -0
  390. package/dist/shared/channel/run-dir.d.ts +6 -1
  391. package/dist/shared/channel/run-dir.js +12 -1
  392. package/dist/shared/channel/schema.d.ts +19 -0
  393. package/dist/shared/channel/schema.js +11 -0
  394. package/dist/shared/channel/secrets.d.ts +28 -0
  395. package/dist/shared/channel/secrets.js +44 -0
  396. package/dist/shared/vpn/download.d.ts +13 -0
  397. package/dist/shared/vpn/download.js +14 -0
  398. package/dist/shared/vpn/kill-switch.d.ts +18 -0
  399. package/dist/shared/vpn/kill-switch.js +81 -0
  400. package/dist/shared/vpn/ovpn.d.ts +23 -0
  401. package/dist/shared/vpn/ovpn.js +244 -0
  402. package/dist/shared/web/index.d.ts +1 -0
  403. package/dist/shared/web/index.js +1 -0
  404. package/dist/shared/web/protocol.d.ts +61 -0
  405. package/dist/shared/web/protocol.js +35 -0
  406. package/dist/sync/sync-cycle.js +5 -1
  407. package/dist/sync/sync-state.d.ts +1 -0
  408. package/dist/sync/sync-state.js +1 -0
  409. package/dist/sync/watcher.js +10 -0
  410. package/dist/web/index.html +13 -0
  411. package/dist/web/main-CXESL347.js +45 -0
  412. package/dist/web/main-VLR7DVQ4.css +1 -0
  413. package/native/csharp/FolderSecurity.cs +29 -0
  414. package/native/scripts/protect-data.ps1 +29 -0
  415. package/native/scripts/read-folder-sddl.ps1 +10 -0
  416. package/native/scripts/set-folder-access.ps1 +49 -7
  417. package/node_modules/ws/LICENSE +20 -0
  418. package/node_modules/ws/README.md +548 -0
  419. package/node_modules/ws/browser.js +8 -0
  420. package/node_modules/ws/index.js +22 -0
  421. package/node_modules/ws/lib/buffer-util.js +131 -0
  422. package/node_modules/ws/lib/constants.js +19 -0
  423. package/node_modules/ws/lib/event-target.js +292 -0
  424. package/node_modules/ws/lib/extension.js +203 -0
  425. package/node_modules/ws/lib/limiter.js +55 -0
  426. package/node_modules/ws/lib/permessage-deflate.js +530 -0
  427. package/node_modules/ws/lib/receiver.js +743 -0
  428. package/node_modules/ws/lib/sender.js +607 -0
  429. package/node_modules/ws/lib/stream.js +161 -0
  430. package/node_modules/ws/lib/subprotocol.js +62 -0
  431. package/node_modules/ws/lib/validation.js +152 -0
  432. package/node_modules/ws/lib/websocket-server.js +562 -0
  433. package/node_modules/ws/lib/websocket.js +1421 -0
  434. package/node_modules/ws/package.json +74 -0
  435. package/node_modules/ws/wrapper.mjs +21 -0
  436. package/package.json +15 -5
  437. package/sandbox/csharp/EnvBroadcast.cs +33 -0
  438. package/sandbox/csharp/PathSync.cs +90 -0
  439. package/sandbox/scripts/install-shell-path.ps1 +73 -0
  440. package/sandbox/scripts/set-machine-environment.ps1 +37 -4
  441. package/schemas/config.schema.json +79 -4
  442. package/schemas/sandbox-config.schema.json +14 -1
  443. package/dist/cli/commands/repair/checks.d.ts +0 -2
  444. package/dist/cli/commands/repair/checks.js +0 -246
  445. package/dist/cli/menu/pages/start-page.d.ts +0 -43
  446. package/dist/cli/menu/pages/start-page.js +0 -192
  447. package/dist/cli/tui/tab-bar.d.ts +0 -9
  448. package/dist/cli/tui/tab-bar.js +0 -33
@@ -1363,11 +1363,11 @@ var require_lodash = __commonJS({
1363
1363
  return isFunction(object2[key]);
1364
1364
  });
1365
1365
  }
1366
- function baseGet(object2, path65) {
1367
- path65 = castPath(path65, object2);
1368
- var index = 0, length = path65.length;
1366
+ function baseGet(object2, path68) {
1367
+ path68 = castPath(path68, object2);
1368
+ var index = 0, length = path68.length;
1369
1369
  while (object2 != null && index < length) {
1370
- object2 = object2[toKey(path65[index++])];
1370
+ object2 = object2[toKey(path68[index++])];
1371
1371
  }
1372
1372
  return index && index == length ? object2 : undefined2;
1373
1373
  }
@@ -1431,10 +1431,10 @@ var require_lodash = __commonJS({
1431
1431
  });
1432
1432
  return accumulator;
1433
1433
  }
1434
- function baseInvoke(object2, path65, args) {
1435
- path65 = castPath(path65, object2);
1436
- object2 = parent(object2, path65);
1437
- var func = object2 == null ? object2 : object2[toKey(last(path65))];
1434
+ function baseInvoke(object2, path68, args) {
1435
+ path68 = castPath(path68, object2);
1436
+ object2 = parent(object2, path68);
1437
+ var func = object2 == null ? object2 : object2[toKey(last(path68))];
1438
1438
  return func == null ? undefined2 : apply(func, object2, args);
1439
1439
  }
1440
1440
  function baseIsArguments(value) {
@@ -1590,13 +1590,13 @@ var require_lodash = __commonJS({
1590
1590
  return object2 === source || baseIsMatch(object2, source, matchData);
1591
1591
  };
1592
1592
  }
1593
- function baseMatchesProperty(path65, srcValue) {
1594
- if (isKey(path65) && isStrictComparable(srcValue)) {
1595
- return matchesStrictComparable(toKey(path65), srcValue);
1593
+ function baseMatchesProperty(path68, srcValue) {
1594
+ if (isKey(path68) && isStrictComparable(srcValue)) {
1595
+ return matchesStrictComparable(toKey(path68), srcValue);
1596
1596
  }
1597
1597
  return function(object2) {
1598
- var objValue = get(object2, path65);
1599
- return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path65) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1598
+ var objValue = get(object2, path68);
1599
+ return objValue === undefined2 && objValue === srcValue ? hasIn(object2, path68) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
1600
1600
  };
1601
1601
  }
1602
1602
  function baseMerge(object2, source, srcIndex, customizer, stack) {
@@ -1693,23 +1693,23 @@ var require_lodash = __commonJS({
1693
1693
  });
1694
1694
  }
1695
1695
  function basePick(object2, paths) {
1696
- return basePickBy(object2, paths, function(value, path65) {
1697
- return hasIn(object2, path65);
1696
+ return basePickBy(object2, paths, function(value, path68) {
1697
+ return hasIn(object2, path68);
1698
1698
  });
1699
1699
  }
1700
1700
  function basePickBy(object2, paths, predicate) {
1701
1701
  var index = -1, length = paths.length, result2 = {};
1702
1702
  while (++index < length) {
1703
- var path65 = paths[index], value = baseGet(object2, path65);
1704
- if (predicate(value, path65)) {
1705
- baseSet(result2, castPath(path65, object2), value);
1703
+ var path68 = paths[index], value = baseGet(object2, path68);
1704
+ if (predicate(value, path68)) {
1705
+ baseSet(result2, castPath(path68, object2), value);
1706
1706
  }
1707
1707
  }
1708
1708
  return result2;
1709
1709
  }
1710
- function basePropertyDeep(path65) {
1710
+ function basePropertyDeep(path68) {
1711
1711
  return function(object2) {
1712
- return baseGet(object2, path65);
1712
+ return baseGet(object2, path68);
1713
1713
  };
1714
1714
  }
1715
1715
  function basePullAll(array2, values2, iteratee2, comparator) {
@@ -1783,14 +1783,14 @@ var require_lodash = __commonJS({
1783
1783
  var array2 = values(collection);
1784
1784
  return shuffleSelf(array2, baseClamp(n, 0, array2.length));
1785
1785
  }
1786
- function baseSet(object2, path65, value, customizer) {
1786
+ function baseSet(object2, path68, value, customizer) {
1787
1787
  if (!isObject2(object2)) {
1788
1788
  return object2;
1789
1789
  }
1790
- path65 = castPath(path65, object2);
1791
- var index = -1, length = path65.length, lastIndex = length - 1, nested = object2;
1790
+ path68 = castPath(path68, object2);
1791
+ var index = -1, length = path68.length, lastIndex = length - 1, nested = object2;
1792
1792
  while (nested != null && ++index < length) {
1793
- var key = toKey(path65[index]), newValue = value;
1793
+ var key = toKey(path68[index]), newValue = value;
1794
1794
  if (key === "__proto__" || key === "constructor" || key === "prototype") {
1795
1795
  return object2;
1796
1796
  }
@@ -1798,7 +1798,7 @@ var require_lodash = __commonJS({
1798
1798
  var objValue = nested[key];
1799
1799
  newValue = customizer ? customizer(objValue, key, nested) : undefined2;
1800
1800
  if (newValue === undefined2) {
1801
- newValue = isObject2(objValue) ? objValue : isIndex(path65[index + 1]) ? [] : {};
1801
+ newValue = isObject2(objValue) ? objValue : isIndex(path68[index + 1]) ? [] : {};
1802
1802
  }
1803
1803
  }
1804
1804
  assignValue(nested, key, newValue);
@@ -1964,14 +1964,14 @@ var require_lodash = __commonJS({
1964
1964
  }
1965
1965
  return result2;
1966
1966
  }
1967
- function baseUnset(object2, path65) {
1968
- path65 = castPath(path65, object2);
1969
- var index = -1, length = path65.length;
1967
+ function baseUnset(object2, path68) {
1968
+ path68 = castPath(path68, object2);
1969
+ var index = -1, length = path68.length;
1970
1970
  if (!length) {
1971
1971
  return true;
1972
1972
  }
1973
1973
  while (++index < length) {
1974
- var key = toKey(path65[index]);
1974
+ var key = toKey(path68[index]);
1975
1975
  if (key === "__proto__" && !hasOwnProperty.call(object2, "__proto__")) {
1976
1976
  return false;
1977
1977
  }
@@ -1979,11 +1979,11 @@ var require_lodash = __commonJS({
1979
1979
  return false;
1980
1980
  }
1981
1981
  }
1982
- var obj = parent(object2, path65);
1983
- return obj == null || delete obj[toKey(last(path65))];
1982
+ var obj = parent(object2, path68);
1983
+ return obj == null || delete obj[toKey(last(path68))];
1984
1984
  }
1985
- function baseUpdate(object2, path65, updater, customizer) {
1986
- return baseSet(object2, path65, updater(baseGet(object2, path65)), customizer);
1985
+ function baseUpdate(object2, path68, updater, customizer) {
1986
+ return baseSet(object2, path68, updater(baseGet(object2, path68)), customizer);
1987
1987
  }
1988
1988
  function baseWhile(array2, predicate, isDrop, fromRight) {
1989
1989
  var length = array2.length, index = fromRight ? length : -1;
@@ -2866,11 +2866,11 @@ var require_lodash = __commonJS({
2866
2866
  var match = source.match(reWrapDetails);
2867
2867
  return match ? match[1].split(reSplitDetails) : [];
2868
2868
  }
2869
- function hasPath(object2, path65, hasFunc) {
2870
- path65 = castPath(path65, object2);
2871
- var index = -1, length = path65.length, result2 = false;
2869
+ function hasPath(object2, path68, hasFunc) {
2870
+ path68 = castPath(path68, object2);
2871
+ var index = -1, length = path68.length, result2 = false;
2872
2872
  while (++index < length) {
2873
- var key = toKey(path65[index]);
2873
+ var key = toKey(path68[index]);
2874
2874
  if (!(result2 = object2 != null && hasFunc(object2, key))) {
2875
2875
  break;
2876
2876
  }
@@ -3072,8 +3072,8 @@ var require_lodash = __commonJS({
3072
3072
  return apply(func, this, otherArgs);
3073
3073
  };
3074
3074
  }
3075
- function parent(object2, path65) {
3076
- return path65.length < 2 ? object2 : baseGet(object2, baseSlice(path65, 0, -1));
3075
+ function parent(object2, path68) {
3076
+ return path68.length < 2 ? object2 : baseGet(object2, baseSlice(path68, 0, -1));
3077
3077
  }
3078
3078
  function reorder(array2, indexes) {
3079
3079
  var arrLength = array2.length, length = nativeMin(indexes.length, arrLength), oldArray = copyArray(array2);
@@ -3708,10 +3708,10 @@ var require_lodash = __commonJS({
3708
3708
  }
3709
3709
  return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1;
3710
3710
  }
3711
- var invokeMap = baseRest(function(collection, path65, args) {
3712
- var index = -1, isFunc = typeof path65 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3711
+ var invokeMap = baseRest(function(collection, path68, args) {
3712
+ var index = -1, isFunc = typeof path68 == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
3713
3713
  baseEach(collection, function(value) {
3714
- result2[++index] = isFunc ? apply(path65, value, args) : baseInvoke(value, path65, args);
3714
+ result2[++index] = isFunc ? apply(path68, value, args) : baseInvoke(value, path68, args);
3715
3715
  });
3716
3716
  return result2;
3717
3717
  });
@@ -4363,15 +4363,15 @@ var require_lodash = __commonJS({
4363
4363
  function functionsIn(object2) {
4364
4364
  return object2 == null ? [] : baseFunctions(object2, keysIn(object2));
4365
4365
  }
4366
- function get(object2, path65, defaultValue) {
4367
- var result2 = object2 == null ? undefined2 : baseGet(object2, path65);
4366
+ function get(object2, path68, defaultValue) {
4367
+ var result2 = object2 == null ? undefined2 : baseGet(object2, path68);
4368
4368
  return result2 === undefined2 ? defaultValue : result2;
4369
4369
  }
4370
- function has(object2, path65) {
4371
- return object2 != null && hasPath(object2, path65, baseHas);
4370
+ function has(object2, path68) {
4371
+ return object2 != null && hasPath(object2, path68, baseHas);
4372
4372
  }
4373
- function hasIn(object2, path65) {
4374
- return object2 != null && hasPath(object2, path65, baseHasIn);
4373
+ function hasIn(object2, path68) {
4374
+ return object2 != null && hasPath(object2, path68, baseHasIn);
4375
4375
  }
4376
4376
  var invert = createInverter(function(result2, value, key) {
4377
4377
  if (value != null && typeof value.toString != "function") {
@@ -4424,10 +4424,10 @@ var require_lodash = __commonJS({
4424
4424
  return result2;
4425
4425
  }
4426
4426
  var isDeep = false;
4427
- paths = arrayMap(paths, function(path65) {
4428
- path65 = castPath(path65, object2);
4429
- isDeep || (isDeep = path65.length > 1);
4430
- return path65;
4427
+ paths = arrayMap(paths, function(path68) {
4428
+ path68 = castPath(path68, object2);
4429
+ isDeep || (isDeep = path68.length > 1);
4430
+ return path68;
4431
4431
  });
4432
4432
  copyObject(object2, getAllKeysIn(object2), result2);
4433
4433
  if (isDeep) {
@@ -4453,19 +4453,19 @@ var require_lodash = __commonJS({
4453
4453
  return [prop];
4454
4454
  });
4455
4455
  predicate = getIteratee(predicate);
4456
- return basePickBy(object2, props, function(value, path65) {
4457
- return predicate(value, path65[0]);
4456
+ return basePickBy(object2, props, function(value, path68) {
4457
+ return predicate(value, path68[0]);
4458
4458
  });
4459
4459
  }
4460
- function result(object2, path65, defaultValue) {
4461
- path65 = castPath(path65, object2);
4462
- var index = -1, length = path65.length;
4460
+ function result(object2, path68, defaultValue) {
4461
+ path68 = castPath(path68, object2);
4462
+ var index = -1, length = path68.length;
4463
4463
  if (!length) {
4464
4464
  length = 1;
4465
4465
  object2 = undefined2;
4466
4466
  }
4467
4467
  while (++index < length) {
4468
- var value = object2 == null ? undefined2 : object2[toKey(path65[index])];
4468
+ var value = object2 == null ? undefined2 : object2[toKey(path68[index])];
4469
4469
  if (value === undefined2) {
4470
4470
  index = length;
4471
4471
  value = defaultValue;
@@ -4474,12 +4474,12 @@ var require_lodash = __commonJS({
4474
4474
  }
4475
4475
  return object2;
4476
4476
  }
4477
- function set2(object2, path65, value) {
4478
- return object2 == null ? object2 : baseSet(object2, path65, value);
4477
+ function set2(object2, path68, value) {
4478
+ return object2 == null ? object2 : baseSet(object2, path68, value);
4479
4479
  }
4480
- function setWith(object2, path65, value, customizer) {
4480
+ function setWith(object2, path68, value, customizer) {
4481
4481
  customizer = typeof customizer == "function" ? customizer : undefined2;
4482
- return object2 == null ? object2 : baseSet(object2, path65, value, customizer);
4482
+ return object2 == null ? object2 : baseSet(object2, path68, value, customizer);
4483
4483
  }
4484
4484
  var toPairs = createToPairs(keys);
4485
4485
  var toPairsIn = createToPairs(keysIn);
@@ -4501,15 +4501,15 @@ var require_lodash = __commonJS({
4501
4501
  });
4502
4502
  return accumulator;
4503
4503
  }
4504
- function unset(object2, path65) {
4505
- return object2 == null ? true : baseUnset(object2, path65);
4504
+ function unset(object2, path68) {
4505
+ return object2 == null ? true : baseUnset(object2, path68);
4506
4506
  }
4507
- function update(object2, path65, updater) {
4508
- return object2 == null ? object2 : baseUpdate(object2, path65, castFunction(updater));
4507
+ function update(object2, path68, updater) {
4508
+ return object2 == null ? object2 : baseUpdate(object2, path68, castFunction(updater));
4509
4509
  }
4510
- function updateWith(object2, path65, updater, customizer) {
4510
+ function updateWith(object2, path68, updater, customizer) {
4511
4511
  customizer = typeof customizer == "function" ? customizer : undefined2;
4512
- return object2 == null ? object2 : baseUpdate(object2, path65, castFunction(updater), customizer);
4512
+ return object2 == null ? object2 : baseUpdate(object2, path68, castFunction(updater), customizer);
4513
4513
  }
4514
4514
  function values(object2) {
4515
4515
  return object2 == null ? [] : baseValues(object2, keys(object2));
@@ -4895,17 +4895,17 @@ var require_lodash = __commonJS({
4895
4895
  function matches(source) {
4896
4896
  return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
4897
4897
  }
4898
- function matchesProperty(path65, srcValue) {
4899
- return baseMatchesProperty(path65, baseClone(srcValue, CLONE_DEEP_FLAG));
4898
+ function matchesProperty(path68, srcValue) {
4899
+ return baseMatchesProperty(path68, baseClone(srcValue, CLONE_DEEP_FLAG));
4900
4900
  }
4901
- var method = baseRest(function(path65, args) {
4901
+ var method = baseRest(function(path68, args) {
4902
4902
  return function(object2) {
4903
- return baseInvoke(object2, path65, args);
4903
+ return baseInvoke(object2, path68, args);
4904
4904
  };
4905
4905
  });
4906
4906
  var methodOf = baseRest(function(object2, args) {
4907
- return function(path65) {
4908
- return baseInvoke(object2, path65, args);
4907
+ return function(path68) {
4908
+ return baseInvoke(object2, path68, args);
4909
4909
  };
4910
4910
  });
4911
4911
  function mixin(object2, source, options) {
@@ -4952,12 +4952,12 @@ var require_lodash = __commonJS({
4952
4952
  var over = createOver(arrayMap);
4953
4953
  var overEvery = createOver(arrayEvery);
4954
4954
  var overSome = createOver(arraySome);
4955
- function property(path65) {
4956
- return isKey(path65) ? baseProperty(toKey(path65)) : basePropertyDeep(path65);
4955
+ function property(path68) {
4956
+ return isKey(path68) ? baseProperty(toKey(path68)) : basePropertyDeep(path68);
4957
4957
  }
4958
4958
  function propertyOf(object2) {
4959
- return function(path65) {
4960
- return object2 == null ? undefined2 : baseGet(object2, path65);
4959
+ return function(path68) {
4960
+ return object2 == null ? undefined2 : baseGet(object2, path68);
4961
4961
  };
4962
4962
  }
4963
4963
  var range = createRange();
@@ -5410,12 +5410,12 @@ var require_lodash = __commonJS({
5410
5410
  LazyWrapper.prototype.findLast = function(predicate) {
5411
5411
  return this.reverse().find(predicate);
5412
5412
  };
5413
- LazyWrapper.prototype.invokeMap = baseRest(function(path65, args) {
5414
- if (typeof path65 == "function") {
5413
+ LazyWrapper.prototype.invokeMap = baseRest(function(path68, args) {
5414
+ if (typeof path68 == "function") {
5415
5415
  return new LazyWrapper(this);
5416
5416
  }
5417
5417
  return this.map(function(value) {
5418
- return baseInvoke(value, path65, args);
5418
+ return baseInvoke(value, path68, args);
5419
5419
  });
5420
5420
  });
5421
5421
  LazyWrapper.prototype.reject = function(predicate) {
@@ -6366,10 +6366,10 @@ function mergeDefs(...defs) {
6366
6366
  function cloneDef(schema) {
6367
6367
  return mergeDefs(schema._zod.def);
6368
6368
  }
6369
- function getElementAtPath(obj, path65) {
6370
- if (!path65)
6369
+ function getElementAtPath(obj, path68) {
6370
+ if (!path68)
6371
6371
  return obj;
6372
- return path65.reduce((acc, key) => acc?.[key], obj);
6372
+ return path68.reduce((acc, key) => acc?.[key], obj);
6373
6373
  }
6374
6374
  function promiseAllObject(promisesObj) {
6375
6375
  const keys = Object.keys(promisesObj);
@@ -6709,11 +6709,11 @@ function explicitlyAborted(x, startIndex = 0) {
6709
6709
  }
6710
6710
  return false;
6711
6711
  }
6712
- function prefixIssues(path65, issues) {
6712
+ function prefixIssues(path68, issues) {
6713
6713
  return issues.map((iss) => {
6714
6714
  var _a3;
6715
6715
  (_a3 = iss).path ?? (_a3.path = []);
6716
- iss.path.unshift(path65);
6716
+ iss.path.unshift(path68);
6717
6717
  return iss;
6718
6718
  });
6719
6719
  }
@@ -6983,8 +6983,8 @@ var _E = "captureStackTrace" in Error ? Error : null;
6983
6983
  function newError(Definition) {
6984
6984
  const E = _E;
6985
6985
  if (E) {
6986
- const saved = E.stackTraceLimit;
6987
- if (typeof saved === "number") {
6986
+ const saved2 = E.stackTraceLimit;
6987
+ if (typeof saved2 === "number") {
6988
6988
  try {
6989
6989
  E.stackTraceLimit = 0;
6990
6990
  } catch {
@@ -6994,7 +6994,7 @@ function newError(Definition) {
6994
6994
  try {
6995
6995
  return new Definition();
6996
6996
  } finally {
6997
- E.stackTraceLimit = saved;
6997
+ E.stackTraceLimit = saved2;
6998
6998
  }
6999
6999
  }
7000
7000
  }
@@ -7163,16 +7163,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
7163
7163
  }
7164
7164
  function formatError(error62, mapper = (issue2) => issue2.message) {
7165
7165
  const fieldErrors = { _errors: [] };
7166
- const processError = (error63, path65 = []) => {
7166
+ const processError = (error63, path68 = []) => {
7167
7167
  for (const issue2 of error63.issues) {
7168
7168
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7169
- issue2.errors.map((issues) => processError({ issues }, [...path65, ...issue2.path]));
7169
+ issue2.errors.map((issues) => processError({ issues }, [...path68, ...issue2.path]));
7170
7170
  } else if (issue2.code === "invalid_key") {
7171
- processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
7171
+ processError({ issues: issue2.issues }, [...path68, ...issue2.path]);
7172
7172
  } else if (issue2.code === "invalid_element") {
7173
- processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
7173
+ processError({ issues: issue2.issues }, [...path68, ...issue2.path]);
7174
7174
  } else {
7175
- const fullpath = [...path65, ...issue2.path];
7175
+ const fullpath = [...path68, ...issue2.path];
7176
7176
  if (fullpath.length === 0) {
7177
7177
  fieldErrors._errors.push(mapper(issue2));
7178
7178
  } else {
@@ -7211,17 +7211,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
7211
7211
  }
7212
7212
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
7213
7213
  const result = { errors: [] };
7214
- const processError = (error63, path65 = []) => {
7214
+ const processError = (error63, path68 = []) => {
7215
7215
  var _a3;
7216
7216
  for (const issue2 of error63.issues) {
7217
7217
  if (issue2.code === "invalid_union" && issue2.errors.length) {
7218
- issue2.errors.map((issues) => processError({ issues }, [...path65, ...issue2.path]));
7218
+ issue2.errors.map((issues) => processError({ issues }, [...path68, ...issue2.path]));
7219
7219
  } else if (issue2.code === "invalid_key") {
7220
- processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
7220
+ processError({ issues: issue2.issues }, [...path68, ...issue2.path]);
7221
7221
  } else if (issue2.code === "invalid_element") {
7222
- processError({ issues: issue2.issues }, [...path65, ...issue2.path]);
7222
+ processError({ issues: issue2.issues }, [...path68, ...issue2.path]);
7223
7223
  } else {
7224
- const fullpath = [...path65, ...issue2.path];
7224
+ const fullpath = [...path68, ...issue2.path];
7225
7225
  if (fullpath.length === 0) {
7226
7226
  result.errors.push(mapper(issue2));
7227
7227
  continue;
@@ -7260,8 +7260,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
7260
7260
  }
7261
7261
  function toDotPath(_path) {
7262
7262
  const segs = [];
7263
- const path65 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
- for (const seg of path65) {
7263
+ const path68 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
7264
+ for (const seg of path68) {
7265
7265
  if (typeof seg === "number")
7266
7266
  segs.push(`[${seg}]`);
7267
7267
  else if (typeof seg === "symbol")
@@ -24363,13 +24363,13 @@ function resolveRef(ref, ctx) {
24363
24363
  if (!ref.startsWith("#")) {
24364
24364
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24365
24365
  }
24366
- const path65 = ref.slice(1).split("/").filter(Boolean);
24367
- if (path65.length === 0) {
24366
+ const path68 = ref.slice(1).split("/").filter(Boolean);
24367
+ if (path68.length === 0) {
24368
24368
  return ctx.rootSchema;
24369
24369
  }
24370
24370
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24371
- if (path65[0] === defsKey) {
24372
- const key = path65[1] === void 0 ? void 0 : decodeJSONPointerSegment(path65[1]);
24371
+ if (path68[0] === defsKey) {
24372
+ const key = path68[1] === void 0 ? void 0 : decodeJSONPointerSegment(path68[1]);
24373
24373
  if (!key || !ctx.defs[key]) {
24374
24374
  throw new Error(`Reference not found: ${ref}`);
24375
24375
  }
@@ -25318,6 +25318,9 @@ function enabled(what, markers) {
25318
25318
  function Packages(what, example) {
25319
25319
  return StringsSchema.describe(what + ", installed once and kept (e.g. " + example + ").");
25320
25320
  }
25321
+ function secret(schema) {
25322
+ return schema.meta({ secret: true });
25323
+ }
25321
25324
 
25322
25325
  // src/core/schema/config.ts
25323
25326
  var import_lodash = __toESM(require_lodash(), 1);
@@ -25386,10 +25389,15 @@ var HarnessSchema = external_exports.strictObject({
25386
25389
  uvPackage: external_exports.string().optional().describe("Python package installed with `uv tool install` inside the sandbox (e.g. aider-chat)."),
25387
25390
  uvBin: external_exports.string().optional().describe("Command the uv package provides."),
25388
25391
  arguments: StringsSchema.describe("Arguments always passed to the agent."),
25389
- environment: external_exports.record(external_exports.string(), external_exports.string()).describe("Environment variables for the agent."),
25392
+ environment: external_exports.record(external_exports.string(), secret(external_exports.string())).describe(
25393
+ "Environment variables for the agent (API keys go here). Their values are shown as *** and are handed to the sandbox in a one-shot file, never kept in the launch folder. The agent can read its own environment."
25394
+ ),
25390
25395
  home: HarnessHomeSchema.optional().describe(
25391
25396
  "Where its login lives inside the sandbox; leave out when the agent cannot be pointed at a folder (then its login is not kept between sandboxes)."
25392
25397
  ),
25398
+ localState: external_exports.record(external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/), SubfolderSchema).optional().describe(
25399
+ "Environment variable -> folder below the agent's own state folder (state\\<agent>) for SQLite databases. SQLite cannot run in a mapped folder, so the agent runs from a copy on the sandbox's disk (the variable points to it) that is copied from and back to that folder."
25400
+ ),
25393
25401
  resumeArguments: StringsSchema.optional().describe(
25394
25402
  "Arguments used when the agent is restarted in place (e.g. after an account switch) so it resumes the conversation."
25395
25403
  ),
@@ -25441,6 +25449,9 @@ var ClaudeProfileSchema = external_exports.strictObject({
25441
25449
  globalStateFile: external_exports.string().describe('Your .claude.json, or "auto". Empty string = do not copy.'),
25442
25450
  copyCredentials: external_exports.boolean().describe("Copy your Claude LOGIN into the sandbox. Prefer sandbox account instead."),
25443
25451
  overwrite: external_exports.boolean().describe("Refresh these settings from this PC on every launch."),
25452
+ sharePluginsAcrossAccounts: external_exports.boolean().describe(
25453
+ "When you switch Claude accounts, copy your Claude plugins (and which ones are enabled) into a data set that has none yet. Off by default: plugins are code that runs in your sessions."
25454
+ ),
25444
25455
  syncHistory: external_exports.boolean().describe("Bring conversation history in, and sync new history back (path-translated)."),
25445
25456
  historyScope: external_exports.enum(["project", "all"]).describe(
25446
25457
  `Which history comes in: "project" = only the projects in this sandbox (other projects' conversations, file backups and prompts stay on this PC), "all" = everything. Only this sandbox's projects ever sync back.`
@@ -25517,7 +25528,10 @@ var NetworkSchema = external_exports.strictObject({
25517
25528
  "Reach servers in the sandbox from this PC: http://localhost:<pc> here goes to <sandbox> inside, while it runs. Nothing else on your network can use them."
25518
25529
  ),
25519
25530
  dns: external_exports.array(external_exports.string().regex(/^\d{1,3}(\.\d{1,3}){3}$/, "an IPv4 address like 1.1.1.1")).describe("DNS servers for the sandbox instead of your network's, e.g. 1.1.1.1 and 9.9.9.9."),
25520
- proxy: external_exports.string().regex(/^(https?:\/\/[^\s]+)?$/, "http://host:port").describe(
25531
+ proxy: external_exports.string().regex(/^(https?:\/\/[^\s]+)?$/, "http://host:port").refine(
25532
+ (v) => !/^https?:\/\/[^/?#]*@/i.test(v),
25533
+ "no user name or password in the address (it would be stored in plain text and visible to the agent): use a proxy that needs no login"
25534
+ ).describe(
25521
25535
  "An HTTP proxy the sandbox uses to reach the internet (HTTP_PROXY / HTTPS_PROXY for everything in it), e.g. http://proxy.corp:8080. Empty = none."
25522
25536
  )
25523
25537
  });
@@ -25919,6 +25933,17 @@ var APPS = [
25919
25933
  exe: "lazygit.exe",
25920
25934
  cli: true
25921
25935
  },
25936
+ {
25937
+ id: "jj",
25938
+ name: "Jujutsu (jj)",
25939
+ category: "git",
25940
+ about: "Git-compatible version control; conflicts do not block a rebase. Pilot, untested with worktrees.",
25941
+ size: "10 MB",
25942
+ source: gh("jj-vcs/jj", "^jj-v[\\d.]+-x86_64-pc-windows-msvc\\.zip$"),
25943
+ exe: "jj.exe",
25944
+ cli: true,
25945
+ fullGitOnly: true
25946
+ },
25922
25947
  // ---- utilities
25923
25948
  {
25924
25949
  id: "7zip",
@@ -26447,6 +26472,26 @@ var APPS = [
26447
26472
  source: gh("gitleaks/gitleaks", "^gitleaks_[\\d.]+_windows_x64\\.zip$"),
26448
26473
  exe: "gitleaks.exe",
26449
26474
  cli: true
26475
+ },
26476
+ {
26477
+ id: "ast-grep",
26478
+ name: "ast-grep",
26479
+ category: "cli",
26480
+ about: "Search and rewrite code by its syntax tree (ast-grep, sg); prints only the matches.",
26481
+ size: "15 MB",
26482
+ source: gh("ast-grep/ast-grep", "^app-x86_64-pc-windows-msvc\\.zip$"),
26483
+ exe: "ast-grep.exe",
26484
+ cli: true
26485
+ },
26486
+ {
26487
+ id: "rust-analyzer",
26488
+ name: "rust-analyzer",
26489
+ category: "cli",
26490
+ about: "Rust language server: type errors and go-to-definition without cargo (for editors and the Claude LSP plugin).",
26491
+ size: "18 MB",
26492
+ source: gh("rust-lang/rust-analyzer", "^rust-analyzer-x86_64-pc-windows-msvc\\.zip$"),
26493
+ exe: "rust-analyzer.exe",
26494
+ cli: true
26450
26495
  }
26451
26496
  ];
26452
26497
  function appById(id) {
@@ -26555,6 +26600,33 @@ var ResumeSchema = external_exports.strictObject({
26555
26600
  )
26556
26601
  });
26557
26602
 
26603
+ // src/core/schema/web.ts
26604
+ var WebSchema = external_exports.strictObject({
26605
+ enabled: external_exports.boolean().describe(
26606
+ "(Beta) Allow the web UI: your sandbox sessions in a browser on this PC. Off by default, and nothing starts it by itself yet: sandbox web start works either way and runs it until sandbox web stop (or a restart of the PC)."
26607
+ ),
26608
+ port: external_exports.number().int().min(1024).max(65535).describe("Port of the web UI on 127.0.0.1 (this PC only). Pick another when it is taken.")
26609
+ });
26610
+
26611
+ // src/core/schema/vpn.ts
26612
+ var VPN_PROVIDERS = ["nordvpn", "openvpn-file"];
26613
+ var VpnSchema = external_exports.strictObject({
26614
+ enabled: external_exports.boolean().describe(
26615
+ "Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."
26616
+ ),
26617
+ provider: external_exports.enum(VPN_PROVIDERS).describe(
26618
+ "nordvpn: a recommended NordVPN server is picked at every launch. openvpn-file: your own .ovpn file (configFile)."
26619
+ ),
26620
+ protocol: external_exports.enum(["udp", "tcp"]).describe("udp is faster; tcp gets through networks that block udp."),
26621
+ country: external_exports.string().regex(/^([A-Za-z][A-Za-z .'-]{0,39})?$/, "a country name or code like uk or Germany").describe("nordvpn: the country of the server, e.g. uk, us or Germany. Empty = the best server anywhere."),
26622
+ configFile: external_exports.string().describe(
26623
+ "openvpn-file: the .ovpn file on this PC (its certificates inside it). Files that run programs (script-security, up, down, plugin ...) are refused. A project's file can never set this."
26624
+ ),
26625
+ killSwitch: external_exports.boolean().describe(
26626
+ "Block all traffic that does not go through the tunnel: when the tunnel cannot start, the sandbox stays offline instead of using your normal connection. A project can only turn this on, never off."
26627
+ )
26628
+ });
26629
+
26558
26630
  // src/core/schema/config.ts
26559
26631
  var ConfigSchema = external_exports.strictObject({
26560
26632
  $schema: SchemaRefSchema.optional(),
@@ -26567,7 +26639,9 @@ var ConfigSchema = external_exports.strictObject({
26567
26639
  sandbox: SandboxSchema,
26568
26640
  sharing: SharingSchema,
26569
26641
  storage: external_exports.strictObject({
26570
- root: external_exports.string().min(1).describe("Where everything is kept on this PC (tools, databases, logins, launches)."),
26642
+ root: external_exports.string().min(1).describe(
26643
+ "Where everything is kept on this PC (tools, databases, logins, launches). The default is a private folder for you under %ProgramData%\\AgentSandbox\\users, which works for installs for one user and for everyone. sandbox storage move <folder> moves it."
26644
+ ),
26571
26645
  persistAgentState: external_exports.boolean().describe("Keep agent logins and history between sandboxes."),
26572
26646
  dataName: NameSchema.describe("Name of the persistent data set (C:\\AgentData) shared by all workspaces."),
26573
26647
  markSandboxFiles: external_exports.boolean().describe(
@@ -26578,6 +26652,7 @@ var ConfigSchema = external_exports.strictObject({
26578
26652
  )
26579
26653
  }),
26580
26654
  network: NetworkSchema,
26655
+ vpn: VpnSchema,
26581
26656
  provisioning: ProvisioningSchema,
26582
26657
  downloads: DownloadsSchema,
26583
26658
  toolchains: ToolchainsSchema,
@@ -26585,6 +26660,7 @@ var ConfigSchema = external_exports.strictObject({
26585
26660
  "Databases running inside the sandbox. Data persists in C:\\AgentData\\databases; each one starts at boot."
26586
26661
  ),
26587
26662
  attach: AttachSchema,
26663
+ web: WebSchema,
26588
26664
  agentCommands: AgentCommandsSchema,
26589
26665
  secrets: SecretsSchema,
26590
26666
  personalization: toggle("Copy your desktop look (theme, accent, taskbar, wallpaper, ...) into the sandbox."),
@@ -26617,6 +26693,8 @@ var LocalOverridesSchema = external_exports.strictObject({
26617
26693
  sandbox: SandboxSchema.omit({ cpuLimit: true, pageFileMb: true }).partial(),
26618
26694
  // A project may block more (the LAN, hosts); it never opens hosts, ports, DNS or a proxy.
26619
26695
  network: NetworkSchema.pick({ blockPrivateRanges: true, blockHosts: true }).partial(),
26696
+ // A project may turn the kill switch on, never off, and never choose a VPN, a server, a file or a login.
26697
+ vpn: VpnSchema.pick({ killSwitch: true }).partial(),
26620
26698
  provisioning: ProvisioningSchema.pick({ copyFromHost: true, fallbackToInstall: true, refresh: true }).extend({ git: GitSchema.partial(), terminal: toggle("Windows Terminal as the sandbox window.").partial() }).partial(),
26621
26699
  downloads: DownloadsSchema.partial(),
26622
26700
  // Every toolchain setting, each one optional (a project usually only switches languages on or pins a version).
@@ -26757,6 +26835,16 @@ var ProjectStatusSchema = external_exports.object({
26757
26835
  databases: external_exports.array(external_exports.object({ database: Text(32), port: external_exports.number().int() })).max(16),
26758
26836
  summary: external_exports.array(Text(512)).max(64)
26759
26837
  });
26838
+ var VpnStatusSchema = external_exports.object({
26839
+ state: external_exports.enum(["off", "starting", "up", "failed"]),
26840
+ message: Text(2e3),
26841
+ killSwitch: external_exports.boolean(),
26842
+ /** The server's name, e.g. uk2201.nordvpn.com. */
26843
+ server: Text(128).optional(),
26844
+ /** What the sandbox's traffic looks like from outside, once the tunnel is up. */
26845
+ publicIp: Text(64).optional(),
26846
+ updatedAt: TimeSchema
26847
+ });
26760
26848
 
26761
26849
  // src/shared/io/json.ts
26762
26850
  import fs2 from "node:fs";
@@ -26920,20 +27008,25 @@ var scan = (schema, dir) => {
26920
27008
  var RunDir = class {
26921
27009
  root;
26922
27010
  sandboxFile;
27011
+ vpnFile;
26923
27012
  requestsDir;
26924
27013
  responsesDir;
26925
27014
  sessionsDir;
26926
27015
  projectsDir;
26927
27016
  /** audit.processes: programs the sandbox started, in small .jsonl files the host takes in and deletes. */
26928
27017
  auditDir;
27018
+ /** One-shot secrets the host hands over (see secrets.ts). Next to run, not in it: shared-use users can change run. */
27019
+ secretsDir;
26929
27020
  constructor(dataDir2) {
26930
27021
  this.root = path6.join(dataDir2, "run");
26931
27022
  this.sandboxFile = path6.join(this.root, "sandbox.json");
27023
+ this.vpnFile = path6.join(this.root, "vpn.json");
26932
27024
  this.requestsDir = path6.join(this.root, "requests");
26933
27025
  this.responsesDir = path6.join(this.root, "responses");
26934
27026
  this.sessionsDir = path6.join(this.root, "sessions");
26935
27027
  this.projectsDir = path6.join(this.root, "projects");
26936
27028
  this.auditDir = path6.join(this.root, "audit");
27029
+ this.secretsDir = path6.join(dataDir2, "secrets");
26937
27030
  }
26938
27031
  requestFile(id) {
26939
27032
  return path6.join(this.requestsDir, safeId(id) + ".json");
@@ -26947,9 +27040,15 @@ var RunDir = class {
26947
27040
  projectFile(name) {
26948
27041
  return path6.join(this.projectsDir, safeId(name) + ".json");
26949
27042
  }
27043
+ secretFile(id) {
27044
+ return path6.join(this.secretsDir, safeId(id) + ".json");
27045
+ }
26950
27046
  readSandboxStatus() {
26951
27047
  return readValid(SandboxStatusSchema, this.sandboxFile);
26952
27048
  }
27049
+ readVpnStatus() {
27050
+ return readValid(VpnStatusSchema, this.vpnFile);
27051
+ }
26953
27052
  readSession(id) {
26954
27053
  return readValid(SessionStatusSchema, this.sessionFile(id));
26955
27054
  }
@@ -27468,16 +27567,94 @@ function safely(what, work) {
27468
27567
  }
27469
27568
  }
27470
27569
 
27570
+ // src/guest/runtime/secrets.ts
27571
+ import fs12 from "node:fs";
27572
+
27573
+ // src/shared/channel/secrets.ts
27574
+ var Environment = external_exports.record(external_exports.string().max(256), external_exports.string().max(65536));
27575
+ var SecretsFileSchema = external_exports.strictObject({
27576
+ /** The agent the sandbox booted with: its harness environment. */
27577
+ harnessEnvironment: Environment.optional(),
27578
+ /** harnessSpec of a session request (an agent the sandbox did not boot with). */
27579
+ harnessSpecEnvironment: Environment.optional(),
27580
+ /** project.harnesses of a request, by agent name. */
27581
+ projectHarnessEnvironment: external_exports.record(external_exports.string().max(64), Environment).optional(),
27582
+ /** The login of this PC's Claude (claudeProfile.copyCredentials): the text of .credentials.json. */
27583
+ claudeCredentials: external_exports.string().max(1024 * 1024).optional(),
27584
+ /** VPN service credentials (vpn.provider's login), only for the launch's own sandbox. */
27585
+ vpn: external_exports.strictObject({ username: external_exports.string().min(1).max(256), password: external_exports.string().min(1).max(1024) }).optional()
27586
+ });
27587
+ var withEnvironment = (harness, environment) => environment ? { ...harness, environment: { ...harness.environment, ...environment } } : harness;
27588
+ function mergeRequestSecrets(request, secrets) {
27589
+ let merged = request;
27590
+ if (request.harnessSpec && secrets.harnessSpecEnvironment)
27591
+ merged = { ...merged, harnessSpec: withEnvironment(request.harnessSpec, secrets.harnessSpecEnvironment) };
27592
+ if (request.project && secrets.projectHarnessEnvironment) {
27593
+ const given = secrets.projectHarnessEnvironment;
27594
+ merged = {
27595
+ ...merged,
27596
+ project: {
27597
+ ...request.project,
27598
+ harnesses: Object.fromEntries(
27599
+ Object.entries(request.project.harnesses).map(([name, h]) => [name, withEnvironment(h, given[name])])
27600
+ )
27601
+ }
27602
+ };
27603
+ }
27604
+ return merged;
27605
+ }
27606
+
27607
+ // src/guest/runtime/secrets.ts
27608
+ var BOOT_SECRETS_VARIABLE = "SBX_BOOT_SECRETS";
27609
+ var MAX_BYTES = 4 * 1024 * 1024;
27610
+ function takeSecrets(id) {
27611
+ const file3 = run.secretFile(id);
27612
+ let text;
27613
+ try {
27614
+ if (fs12.statSync(file3).size > MAX_BYTES) throw new Error("too big");
27615
+ text = fs12.readFileSync(file3, "utf8").replace(/^\uFEFF/, "");
27616
+ } catch {
27617
+ return {};
27618
+ } finally {
27619
+ fs12.rmSync(file3, { force: true });
27620
+ }
27621
+ try {
27622
+ const parsed = SecretsFileSchema.safeParse(JSON.parse(text));
27623
+ if (parsed.success) return parsed.data;
27624
+ } catch {
27625
+ }
27626
+ warn("The secrets file for " + id + " was not valid and was ignored.");
27627
+ return {};
27628
+ }
27629
+ function applyBootEnvironment(environment) {
27630
+ if (session.harness && environment) session.harness.environment = { ...environment };
27631
+ }
27632
+ function adoptBootSecrets() {
27633
+ const text = process.env[BOOT_SECRETS_VARIABLE];
27634
+ delete process.env[BOOT_SECRETS_VARIABLE];
27635
+ if (!text) return;
27636
+ try {
27637
+ const parsed = SecretsFileSchema.pick({ harnessEnvironment: true }).safeParse(JSON.parse(text));
27638
+ if (parsed.success) applyBootEnvironment(parsed.data.harnessEnvironment);
27639
+ } catch {
27640
+ warn("The boot secrets given to the daemon were not valid.");
27641
+ }
27642
+ }
27643
+ function withRequestSecrets(req) {
27644
+ if (req.kind !== "session" && req.kind !== "project") return req;
27645
+ return mergeRequestSecrets(req, takeSecrets(req.id));
27646
+ }
27647
+
27471
27648
  // src/guest/daemon/daemon.ts
27472
- import fs50 from "node:fs";
27649
+ import fs52 from "node:fs";
27473
27650
 
27474
27651
  // src/guest/setup/claude-mem.ts
27475
- import fs13 from "node:fs";
27652
+ import fs14 from "node:fs";
27476
27653
  import os4 from "node:os";
27477
27654
  import path18 from "node:path";
27478
27655
 
27479
27656
  // src/guest/runtime/process.ts
27480
- import fs12 from "node:fs";
27657
+ import fs13 from "node:fs";
27481
27658
  import os3 from "node:os";
27482
27659
  import path17 from "node:path";
27483
27660
  import { spawnSync as spawnSync2 } from "node:child_process";
@@ -27503,24 +27680,24 @@ function scriptOutput(name, args = [], options = {}) {
27503
27680
  return execOutput(SYSTEM.powershell(), scriptArgs(name, args), options);
27504
27681
  }
27505
27682
  function runScriptWithJson(name, param, data, args = []) {
27506
- const dir = fs12.mkdtempSync(path17.join(os3.tmpdir(), "sbx-"));
27683
+ const dir = fs13.mkdtempSync(path17.join(os3.tmpdir(), "sbx-"));
27507
27684
  const file3 = path17.join(dir, "input.json");
27508
27685
  try {
27509
- fs12.writeFileSync(file3, JSON.stringify(data), "utf8");
27686
+ fs13.writeFileSync(file3, JSON.stringify(data), "utf8");
27510
27687
  runScript(name, ["-" + param, file3, ...args]);
27511
27688
  } finally {
27512
- fs12.rmSync(dir, { recursive: true, force: true });
27689
+ fs13.rmSync(dir, { recursive: true, force: true });
27513
27690
  }
27514
27691
  }
27515
27692
  function robocopy(from, to, files = []) {
27516
27693
  if (!isWin) {
27517
27694
  if (!files.length) {
27518
- fs12.cpSync(from, to, { recursive: true });
27695
+ fs13.cpSync(from, to, { recursive: true });
27519
27696
  return;
27520
27697
  }
27521
- fs12.mkdirSync(to, { recursive: true });
27522
- for (const f of files.filter((f2) => fs12.existsSync(path17.join(from, f2))))
27523
- fs12.copyFileSync(path17.join(from, f), path17.join(to, f));
27698
+ fs13.mkdirSync(to, { recursive: true });
27699
+ for (const f of files.filter((f2) => fs13.existsSync(path17.join(from, f2))))
27700
+ fs13.copyFileSync(path17.join(from, f), path17.join(to, f));
27524
27701
  return;
27525
27702
  }
27526
27703
  const what = files.length ? files : ["/E", "/MT:16"];
@@ -27552,11 +27729,11 @@ var claudeMemEnabled = () => session.claudeProfile.syncClaudeMem && !dryRun;
27552
27729
  var databaseFingerprint = (dir) => {
27553
27730
  const parts2 = [];
27554
27731
  const walk = (folder) => {
27555
- for (const entry of fs13.readdirSync(folder, { withFileTypes: true })) {
27732
+ for (const entry of fs14.readdirSync(folder, { withFileTypes: true })) {
27556
27733
  const full = path18.join(folder, entry.name);
27557
27734
  if (entry.isDirectory()) walk(full);
27558
27735
  else if (entry.isFile() && /\.(db|sqlite3?)(-wal)?$/i.test(entry.name)) {
27559
- const s = fs13.statSync(full);
27736
+ const s = fs14.statSync(full);
27560
27737
  parts2.push(full + ":" + s.size + ":" + s.mtimeMs);
27561
27738
  }
27562
27739
  }
@@ -27568,33 +27745,33 @@ var lastSaved = null;
27568
27745
  var SQLITE_HEADER = "SQLite format 3\0";
27569
27746
  var looksLikeSqlite = (file3) => {
27570
27747
  if (!exists(file3)) return true;
27571
- const fd = fs13.openSync(file3, "r");
27748
+ const fd = fs14.openSync(file3, "r");
27572
27749
  try {
27573
27750
  const head = Buffer.alloc(16);
27574
- return fs13.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
27751
+ return fs14.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER;
27575
27752
  } finally {
27576
- fs13.closeSync(fd);
27753
+ fs14.closeSync(fd);
27577
27754
  }
27578
27755
  };
27579
27756
  var MAX_BACKUPS = 3;
27580
27757
  var BACKUP_EVERY_MS = 6 * 3600 * 1e3;
27581
27758
  var keepBackup = (previous, dir) => {
27582
27759
  if (!exists(previous)) return;
27583
- const backups = exists(dir) ? fs13.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
27760
+ const backups = exists(dir) ? fs14.readdirSync(dir).filter((n) => /^\d{13}$/.test(n)).sort() : [];
27584
27761
  const newest = Number(backups[backups.length - 1] ?? 0);
27585
27762
  if (Date.now() - newest < BACKUP_EVERY_MS) {
27586
- fs13.rmSync(previous, { recursive: true, force: true });
27763
+ fs14.rmSync(previous, { recursive: true, force: true });
27587
27764
  return;
27588
27765
  }
27589
- fs13.renameSync(previous, path18.join(mkdirp(dir), String(Date.now())));
27766
+ fs14.renameSync(previous, path18.join(mkdirp(dir), String(Date.now())));
27590
27767
  for (const old of [...backups, String(Date.now())].slice(0, -MAX_BACKUPS))
27591
- fs13.rmSync(path18.join(dir, old), { recursive: true, force: true });
27768
+ fs14.rmSync(path18.join(dir, old), { recursive: true, force: true });
27592
27769
  };
27593
27770
  function saveClaudeMem() {
27594
27771
  if (!claudeMemEnabled() || !exists(claudeMemPaths.local)) return;
27595
27772
  const { store: store2, local } = claudeMemPaths;
27596
- const fingerprint = databaseFingerprint(local);
27597
- if (fingerprint === lastSaved && exists(store2)) return;
27773
+ const fingerprint2 = databaseFingerprint(local);
27774
+ if (fingerprint2 === lastSaved && exists(store2)) return;
27598
27775
  if (!looksLikeSqlite(path18.join(local, "claude-mem.db"))) {
27599
27776
  warn(
27600
27777
  "claude-mem: the local database does not look valid, so it was not saved over the stored copy (" + local + ")."
@@ -27603,30 +27780,287 @@ function saveClaudeMem() {
27603
27780
  }
27604
27781
  const incoming = store2 + ".incoming";
27605
27782
  const previous = store2 + ".previous";
27606
- fs13.rmSync(incoming, { recursive: true, force: true });
27607
- fs13.cpSync(local, incoming, { recursive: true, filter: (src) => !/\.(pid|lock)$/i.test(src) });
27608
- fs13.rmSync(previous, { recursive: true, force: true });
27609
- if (exists(store2)) fs13.renameSync(store2, previous);
27783
+ fs14.rmSync(incoming, { recursive: true, force: true });
27784
+ fs14.cpSync(local, incoming, { recursive: true, filter: (src) => !/\.(pid|lock)$/i.test(src) });
27785
+ fs14.rmSync(previous, { recursive: true, force: true });
27786
+ if (exists(store2)) fs14.renameSync(store2, previous);
27610
27787
  try {
27611
- fs13.renameSync(incoming, store2);
27788
+ fs14.renameSync(incoming, store2);
27612
27789
  } catch (e) {
27613
- if (exists(previous)) fs13.renameSync(previous, store2);
27790
+ if (exists(previous)) fs14.renameSync(previous, store2);
27614
27791
  throw e;
27615
27792
  }
27616
27793
  keepBackup(previous, store2 + ".backups");
27617
- lastSaved = fingerprint;
27794
+ lastSaved = fingerprint2;
27795
+ }
27796
+
27797
+ // src/guest/agents/local-state.ts
27798
+ import fs15 from "node:fs";
27799
+ import path20 from "node:path";
27800
+
27801
+ // src/guest/agents/agent-files.ts
27802
+ import path19 from "node:path";
27803
+ function agentPaths(toolsDir2, name, harness) {
27804
+ const dir = path19.join(toolsDir2, "agents", name);
27805
+ const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
27806
+ return {
27807
+ dir,
27808
+ exe: exe ? path19.join(dir, exe) : null,
27809
+ cmd: harness.npmBin ? path19.join(dir, harness.npmBin + ".cmd") : null
27810
+ };
27811
+ }
27812
+ function agentCommand(name, harness) {
27813
+ return harness.npmBin ?? harness.uvBin ?? (harness.hostExecutable ?? name).replace(/\.exe$/i, "");
27814
+ }
27815
+ function localStateEntries(agents2, stateDir2, localRoot2) {
27816
+ return Object.entries(agents2).flatMap(
27817
+ ([agent, harness]) => Object.entries(harness.localState ?? {}).map(([env, folder]) => ({
27818
+ agent,
27819
+ env,
27820
+ store: path19.join(stateDir2, agent, folder),
27821
+ local: path19.join(localRoot2, agent, folder),
27822
+ processes: [agentCommand(agent, harness) + ".exe"],
27823
+ legacy: path19.join(stateDir2, agent)
27824
+ }))
27825
+ );
27826
+ }
27827
+ var isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
27828
+ var isCopyableDatabaseFile = (name) => isDatabaseFile(name) && !/-shm$/i.test(name);
27829
+
27830
+ // src/guest/agents/local-state.ts
27831
+ var SQLITE_HEADER2 = "SQLite format 3\0";
27832
+ var localRoot = () => path20.join(localDir, "agent-state");
27833
+ function agentLocalStates() {
27834
+ return localStateEntries(session.agents ?? {}, stateDir, localRoot());
27835
+ }
27836
+ function localStateVars() {
27837
+ return Object.fromEntries(agentLocalStates().map((s) => [s.env, s.local]));
27838
+ }
27839
+ var databaseFiles = (dir, keep) => exists(dir) ? fs15.readdirSync(dir, { withFileTypes: true }).flatMap((e) => e.isFile() && keep(e.name) ? [e.name] : []) : [];
27840
+ var looksLikeSqlite2 = (file3) => {
27841
+ const fd = fs15.openSync(file3, "r");
27842
+ try {
27843
+ const head = Buffer.alloc(16);
27844
+ return fs15.readSync(fd, head, 0, 16, 0) === 16 && head.toString("latin1") === SQLITE_HEADER2;
27845
+ } finally {
27846
+ fs15.closeSync(fd);
27847
+ }
27848
+ };
27849
+ var copyFiles = (from, to, names) => {
27850
+ fs15.rmSync(to, { recursive: true, force: true });
27851
+ mkdirp(to);
27852
+ for (const name of names) fs15.copyFileSync(path20.join(from, name), path20.join(to, name));
27853
+ };
27854
+ var swapIn = (incoming, store2) => {
27855
+ const previous = store2 + ".previous";
27856
+ fs15.rmSync(previous, { recursive: true, force: true });
27857
+ if (exists(store2)) fs15.renameSync(store2, previous);
27858
+ try {
27859
+ fs15.renameSync(incoming, store2);
27860
+ } catch (e) {
27861
+ if (exists(previous)) fs15.renameSync(previous, store2);
27862
+ throw e;
27863
+ }
27864
+ fs15.rmSync(previous, { recursive: true, force: true });
27865
+ };
27866
+ function held(s) {
27867
+ if (!isWin) return false;
27868
+ return s.processes.some(
27869
+ (image) => execOutput(SYSTEM.tasklist(), ["/FI", "IMAGENAME eq " + image, "/NH", "/FO", "CSV"]).toLowerCase().includes(image.toLowerCase())
27870
+ );
27871
+ }
27872
+ var fingerprint = (dir) => databaseFiles(dir, isCopyableDatabaseFile).sort().map((n) => {
27873
+ const st = fs15.statSync(path20.join(dir, n));
27874
+ return n + ":" + st.size + ":" + st.mtimeMs;
27875
+ }).join("|");
27876
+ var saved = /* @__PURE__ */ new Map();
27877
+ var snapshotting = /* @__PURE__ */ new Set();
27878
+ var saidNoBackup = false;
27879
+ function snapshotWhileRunning(s, print) {
27880
+ if (snapshotting.has(s.local)) return;
27881
+ snapshotting.add(s.local);
27882
+ void (async () => {
27883
+ try {
27884
+ const sqlite = await import("node:sqlite").catch(() => null);
27885
+ if (!sqlite || typeof sqlite.backup !== "function") {
27886
+ if (!saidNoBackup)
27887
+ log(s.agent + ": this Node has no SQLite online backup; its databases are saved when it exits.");
27888
+ saidNoBackup = true;
27889
+ return;
27890
+ }
27891
+ const incoming = s.store + ".incoming";
27892
+ fs15.rmSync(incoming, { recursive: true, force: true });
27893
+ mkdirp(incoming);
27894
+ for (const name of databaseFiles(s.local, (n) => isCopyableDatabaseFile(n) && !/-wal$/i.test(n))) {
27895
+ const db = new sqlite.DatabaseSync(path20.join(s.local, name), { readOnly: true });
27896
+ try {
27897
+ await sqlite.backup(db, path20.join(incoming, name));
27898
+ } finally {
27899
+ db.close();
27900
+ }
27901
+ }
27902
+ swapIn(incoming, s.store);
27903
+ saved.set(s.local, print);
27904
+ } catch (e) {
27905
+ warn(s.agent + ": could not snapshot its running databases: " + errMsg(e));
27906
+ } finally {
27907
+ snapshotting.delete(s.local);
27908
+ }
27909
+ })();
27910
+ }
27911
+ function saveLocalState() {
27912
+ if (dryRun) return;
27913
+ for (const s of agentLocalStates()) {
27914
+ try {
27915
+ if (!exists(s.local)) continue;
27916
+ const print = fingerprint(s.local);
27917
+ if (!print || saved.get(s.local) === print && exists(s.store)) continue;
27918
+ if (held(s)) {
27919
+ snapshotWhileRunning(s, print);
27920
+ continue;
27921
+ }
27922
+ const names = databaseFiles(s.local, isCopyableDatabaseFile);
27923
+ const bad = names.filter((n) => !/-wal$/i.test(n) && !looksLikeSqlite2(path20.join(s.local, n)));
27924
+ if (bad.length) {
27925
+ warn(s.agent + ": " + bad.join(", ") + " do not look like SQLite databases, so they were not saved.");
27926
+ continue;
27927
+ }
27928
+ const incoming = s.store + ".incoming";
27929
+ copyFiles(s.local, incoming, names);
27930
+ swapIn(incoming, s.store);
27931
+ saved.set(s.local, print);
27932
+ } catch (e) {
27933
+ warn(s.agent + ": could not save its databases: " + errMsg(e));
27934
+ }
27935
+ }
27618
27936
  }
27619
27937
 
27620
27938
  // src/guest/daemon/exec.ts
27621
27939
  import { spawn as spawn5 } from "node:child_process";
27622
27940
 
27941
+ // src/guest/setup/environment.ts
27942
+ import path22 from "node:path";
27943
+
27944
+ // src/guest/setup/path-plan.ts
27945
+ import path21 from "node:path";
27946
+ function pathKey(folder) {
27947
+ const slashes = folder.trim().replace(/^"|"$/g, "").replace(/\//g, "\\");
27948
+ return (slashes.length > 3 ? slashes.replace(/\\+$/, "") : slashes).toLowerCase();
27949
+ }
27950
+ function splitPath(value) {
27951
+ return value.split(";").map((part) => part.trim().replace(/^"|"$/g, "")).filter(Boolean);
27952
+ }
27953
+ function expandVars(value, env) {
27954
+ const lower = new Map(Object.entries(env).map(([k, v]) => [k.toLowerCase(), v]));
27955
+ return value.replace(/%([^%;\\]+)%/g, (whole, name) => lower.get(name.toLowerCase()) ?? whole);
27956
+ }
27957
+ function planPath(input2) {
27958
+ const seen = /* @__PURE__ */ new Set();
27959
+ const result = [];
27960
+ for (const entry of input2.entries.flatMap(splitPath)) {
27961
+ const key = pathKey(entry);
27962
+ if (seen.has(key) || input2.drop?.(entry) || !input2.exists(entry)) continue;
27963
+ seen.add(key);
27964
+ result.push(entry);
27965
+ }
27966
+ return result;
27967
+ }
27968
+ function appendMissing(base, extra, skip = () => false) {
27969
+ const seen = new Set(splitPath(base).map(pathKey));
27970
+ const added = splitPath(extra).filter((folder) => {
27971
+ const key = pathKey(folder);
27972
+ if (seen.has(key) || skip(folder)) return false;
27973
+ seen.add(key);
27974
+ return true;
27975
+ });
27976
+ return [...splitPath(base), ...added].join(";");
27977
+ }
27978
+ function parseRegPath(output2) {
27979
+ const line = output2.split(/\r?\n/).find((l) => /^\s+Path\s+REG_(EXPAND_)?SZ\s/i.test(l));
27980
+ return line ? line.replace(/^\s+Path\s+REG_(EXPAND_)?SZ\s+/i, "").trim() : "";
27981
+ }
27982
+ function isPinnedNodeDir(folder, nvmHome2) {
27983
+ const key = pathKey(folder);
27984
+ const home = pathKey(nvmHome2);
27985
+ return key.startsWith(home + "\\") && /^v\d/.test(path21.win32.basename(key));
27986
+ }
27987
+
27988
+ // src/guest/setup/environment.ts
27989
+ var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
27990
+ var agentHomes = () => Object.fromEntries(
27991
+ Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path22.join(stateDir, sub)])
27992
+ );
27993
+ function agentEnv(tools, target = { workspace, project: session.project, base: process.env }) {
27994
+ const homes = agentHomes();
27995
+ const env = {
27996
+ ...target.base,
27997
+ ...tools.vars,
27998
+ CLAUDE_CONFIG_DIR: claudeDir,
27999
+ ...homes,
28000
+ ...localStateVars(),
28001
+ npm_config_cache: path22.join(toolsDir, "npm-cache"),
28002
+ npm_config_update_notifier: "false",
28003
+ AGENT_WORKSPACE: target.workspace,
28004
+ AGENT_DATA: dataDir,
28005
+ AGENT_TOOLS: toolsDir,
28006
+ AGENT_PROJECT: target.project,
28007
+ // For project scripts: "am I in the sandbox, and where is the project?" (stable names; documented).
28008
+ AGENT_SANDBOX: "1",
28009
+ AGENT_SANDBOX_WORKSPACE: target.workspace
28010
+ };
28011
+ const local = Object.keys(localStateVars());
28012
+ for (const dir of [
28013
+ env.CLAUDE_CONFIG_DIR,
28014
+ ...Object.keys(homes).map((n) => env[n]),
28015
+ env.npm_config_cache,
28016
+ ...local.map((n) => env[n])
28017
+ ])
28018
+ mkdirp(dir);
28019
+ const runners = [path22.join(toolsDir, "node"), path22.dirname(process.execPath)].map((d) => d.toLowerCase());
28020
+ const base = (target.base.PATH ?? "").split(path22.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
28021
+ env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path22.delimiter);
28022
+ return env;
28023
+ }
28024
+ function addMachineEnvironment(vars, dirs, additive = false) {
28025
+ if (!isWin || dryRun || testMode) return;
28026
+ const planned = planPath({ entries: dirs, exists, drop: (dir) => isPinnedNodeDir(dir, nvmHome()) });
28027
+ try {
28028
+ runScriptWithJson("set-machine-environment.ps1", "SettingsFile", { vars, path: null, add: planned, additive });
28029
+ } catch (e) {
28030
+ warn("Could not add to the environment: " + errMsg(e));
28031
+ }
28032
+ }
28033
+ var nvmHome = () => path22.join(toolsDir, "nvm");
28034
+ var MACHINE_ENVIRONMENT_KEY = "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
28035
+ var USER_ENVIRONMENT_KEY = "HKCU\\Environment";
28036
+ var registryPath = (key) => parseRegPath(execOutput(SYSTEM.reg(), ["query", key, "/v", "Path"]));
28037
+ function withRegistryPath(env) {
28038
+ if (!isWin || dryRun || testMode) return env;
28039
+ try {
28040
+ const registry2 = expandVars(registryPath(MACHINE_ENVIRONMENT_KEY) + ";" + registryPath(USER_ENVIRONMENT_KEY), env);
28041
+ const runner = pathKey(path22.join(toolsDir, "node"));
28042
+ const pathName = Object.keys(env).find((k) => k.toLowerCase() === "path") ?? "PATH";
28043
+ return {
28044
+ ...env,
28045
+ [pathName]: appendMissing(
28046
+ env[pathName] ?? "",
28047
+ registry2,
28048
+ (dir) => pathKey(dir) === runner || isPinnedNodeDir(dir, nvmHome())
28049
+ )
28050
+ };
28051
+ } catch (e) {
28052
+ warn("Could not read the machine PATH (the session keeps the one it has): " + errMsg(e));
28053
+ return env;
28054
+ }
28055
+ }
28056
+
27623
28057
  // src/guest/daemon/project-provisioner.ts
27624
- import fs46 from "node:fs";
27625
- import path59 from "node:path";
28058
+ import fs48 from "node:fs";
28059
+ import path62 from "node:path";
27626
28060
 
27627
28061
  // src/guest/boot/boot-env.ts
27628
- import fs14 from "node:fs";
27629
- import path19 from "node:path";
28062
+ import fs16 from "node:fs";
28063
+ import path23 from "node:path";
27630
28064
 
27631
28065
  // src/guest/boot/project-env.ts
27632
28066
  var EnvSchema = external_exports.object({
@@ -27656,22 +28090,22 @@ function baseEnvFor(boot, current = process.env) {
27656
28090
  }
27657
28091
 
27658
28092
  // src/guest/boot/boot-env.ts
27659
- var file2 = () => path19.join(localDir, "boot-env.json");
28093
+ var file2 = () => path23.join(localDir, "boot-env.json");
27660
28094
  function readBootEnv() {
27661
28095
  try {
27662
- return BootEnvSchema.safeParse(JSON.parse(fs14.readFileSync(file2(), "utf8"))).data ?? null;
28096
+ return BootEnvSchema.safeParse(JSON.parse(fs16.readFileSync(file2(), "utf8"))).data ?? null;
27663
28097
  } catch {
27664
28098
  return null;
27665
28099
  }
27666
28100
  }
27667
28101
 
27668
28102
  // src/guest/boot/guide.ts
27669
- import fs15 from "node:fs";
27670
- import path20 from "node:path";
28103
+ import fs17 from "node:fs";
28104
+ import path24 from "node:path";
27671
28105
  var BEGIN = "<!-- agent-sandbox:begin (generated every boot, do not edit) -->";
27672
28106
  var END = "<!-- agent-sandbox:end -->";
27673
28107
  var mirrorLine = () => {
27674
- const drives = (session.substDrives ?? []).filter((d) => fs15.existsSync(d.letter + ":\\"));
28108
+ const drives = (session.substDrives ?? []).filter((d) => fs17.existsSync(d.letter + ":\\"));
27675
28109
  if (!drives.length) return [];
27676
28110
  return [
27677
28111
  "- " + drives.map((d) => d.letter + ":").join(", ") + " = mapped folders at their PC paths (subst onto `" + drives.map((d) => d.target).join("`, `") + "`; real-path tools may print that form)."
@@ -27687,8 +28121,8 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = []) {
27687
28121
  ...projects.map(
27688
28122
  (p) => "- RW, persists: `" + p.guest + "` = host folder " + p.host + " (another project in this sandbox; your own is `%AGENT_WORKSPACE%`)"
27689
28123
  ),
27690
- "- RW, persists: `" + toolsDir + "` (toolchains) \u2014 put portable exes in `" + path20.join(toolsDir, "bin") + "` (on PATH)",
27691
- "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path20.join(dataDir, "logs") + "`",
28124
+ "- RW, persists: `" + toolsDir + "` (toolchains) \u2014 put portable exes in `" + path24.join(toolsDir, "bin") + "` (on PATH)",
28125
+ "- RW, persists: `" + stateDir + "` (agent config/history; do not edit logins) \xB7 logs: `" + path24.join(dataDir, "logs") + "`",
27692
28126
  "- RO: `" + launchDir + "` (this boot's scripts) \xB7 lost on close: everything else, incl. `C:\\nvm` (Node symlink)",
27693
28127
  ...mirrorLine(),
27694
28128
  "- Tools: " + toolSummary.join(" \xB7 "),
@@ -27699,37 +28133,37 @@ function sandboxGuide(toolSummary, lan = "blocked", projects = []) {
27699
28133
  ].join("\n");
27700
28134
  }
27701
28135
  function upsertGuide(file3, guide) {
27702
- fs15.mkdirSync(path20.dirname(file3), { recursive: true });
27703
- const current = fs15.existsSync(file3) ? fs15.readFileSync(file3, "utf8") : "";
28136
+ fs17.mkdirSync(path24.dirname(file3), { recursive: true });
28137
+ const current = fs17.existsSync(file3) ? fs17.readFileSync(file3, "utf8") : "";
27704
28138
  const start = current.indexOf(BEGIN);
27705
28139
  const end = current.indexOf(END);
27706
28140
  const without = start >= 0 && end > start ? current.slice(0, start) + current.slice(end + END.length) : current;
27707
- fs15.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
28141
+ fs17.writeFileSync(file3, without.trimEnd() + (without.trim() ? "\n\n" : "") + guide + "\n", "utf8");
27708
28142
  }
27709
28143
  function managedClaudeMd() {
27710
- return path20.join(
27711
- process.env.AGENT_MANAGED_DIR ?? path20.join(process.env.ProgramFiles ?? "C:\\Program Files", "ClaudeCode"),
28144
+ return path24.join(
28145
+ process.env.AGENT_MANAGED_DIR ?? path24.join(process.env.ProgramFiles ?? "C:\\Program Files", "ClaudeCode"),
27712
28146
  "CLAUDE.md"
27713
28147
  );
27714
28148
  }
27715
28149
  function writeGuides(toolSummary, lan, projects = []) {
27716
28150
  const guide = sandboxGuide(toolSummary, lan, projects);
27717
28151
  const managed = managedClaudeMd();
27718
- fs15.mkdirSync(path20.dirname(managed), { recursive: true });
27719
- fs15.writeFileSync(managed, guide + "\n", "utf8");
27720
- fs15.writeFileSync(path20.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
27721
- upsertGuide(path20.join(stateDir, "codex", "AGENTS.md"), guide);
27722
- upsertGuide(path20.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
27723
- removeGuide(path20.join(claudeDir, "CLAUDE.md"));
28152
+ fs17.mkdirSync(path24.dirname(managed), { recursive: true });
28153
+ fs17.writeFileSync(managed, guide + "\n", "utf8");
28154
+ fs17.writeFileSync(path24.join(dataDir, "SANDBOX.md"), guide + "\n", "utf8");
28155
+ upsertGuide(path24.join(stateDir, "codex", "AGENTS.md"), guide);
28156
+ upsertGuide(path24.join(stateDir, "gemini", ".gemini", "GEMINI.md"), guide);
28157
+ removeGuide(path24.join(claudeDir, "CLAUDE.md"));
27724
28158
  return managed;
27725
28159
  }
27726
28160
  var removeGuide = (file3) => {
27727
- if (!fs15.existsSync(file3)) return;
27728
- const current = fs15.readFileSync(file3, "utf8");
28161
+ if (!fs17.existsSync(file3)) return;
28162
+ const current = fs17.readFileSync(file3, "utf8");
27729
28163
  const start = current.indexOf(BEGIN);
27730
28164
  const end = current.indexOf(END);
27731
28165
  if (start >= 0 && end > start)
27732
- fs15.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
28166
+ fs17.writeFileSync(file3, (current.slice(0, start) + current.slice(end + END.length)).trim() + "\n", "utf8");
27733
28167
  };
27734
28168
 
27735
28169
  // src/guest/runtime/project-context.ts
@@ -27765,51 +28199,12 @@ function saveProjectStatus(name, workspace2, phase, message, databases, summary)
27765
28199
  }
27766
28200
  }
27767
28201
 
27768
- // src/guest/setup/environment.ts
27769
- import path21 from "node:path";
27770
- var LEGACY_HOMES = { CODEX_HOME: "codex", GEMINI_CLI_HOME: "gemini" };
27771
- var agentHomes = () => Object.fromEntries(
27772
- Object.entries(session.agentHomes ?? LEGACY_HOMES).filter(([name]) => name !== "CLAUDE_CONFIG_DIR").map(([name, sub]) => [name, path21.join(stateDir, sub)])
27773
- );
27774
- function agentEnv(tools, target = { workspace, project: session.project, base: process.env }) {
27775
- const homes = agentHomes();
27776
- const env = {
27777
- ...target.base,
27778
- ...tools.vars,
27779
- CLAUDE_CONFIG_DIR: claudeDir,
27780
- ...homes,
27781
- npm_config_cache: path21.join(toolsDir, "npm-cache"),
27782
- npm_config_update_notifier: "false",
27783
- AGENT_WORKSPACE: target.workspace,
27784
- AGENT_DATA: dataDir,
27785
- AGENT_TOOLS: toolsDir,
27786
- AGENT_PROJECT: target.project,
27787
- // For project scripts: "am I in the sandbox, and where is the project?" (stable names; documented).
27788
- AGENT_SANDBOX: "1",
27789
- AGENT_SANDBOX_WORKSPACE: target.workspace
27790
- };
27791
- for (const dir of [env.CLAUDE_CONFIG_DIR, ...Object.keys(homes).map((n) => env[n]), env.npm_config_cache])
27792
- mkdirp(dir);
27793
- const runners = [path21.join(toolsDir, "node"), path21.dirname(process.execPath)].map((d) => d.toLowerCase());
27794
- const base = (target.base.PATH ?? "").split(path21.delimiter).filter((d) => d && !runners.includes(d.toLowerCase()));
27795
- env.PATH = [.../* @__PURE__ */ new Set([...tools.prepend, ...base, ...tools.append])].join(path21.delimiter);
27796
- return env;
27797
- }
27798
- function addMachineEnvironment(vars, dirs, additive = false) {
27799
- if (!isWin || dryRun || testMode) return;
27800
- try {
27801
- runScriptWithJson("set-machine-environment.ps1", "SettingsFile", { vars, path: null, add: dirs, additive });
27802
- } catch (e) {
27803
- warn("Could not add to the environment: " + errMsg(e));
27804
- }
27805
- }
27806
-
27807
28202
  // src/guest/setup/hooks.ts
27808
- import fs16 from "node:fs";
27809
- import path22 from "node:path";
28203
+ import fs18 from "node:fs";
28204
+ import path25 from "node:path";
27810
28205
  import { spawnSync as spawnSync3 } from "node:child_process";
27811
28206
  var commandFor = (file3) => {
27812
- const ext = path22.extname(file3).toLowerCase();
28207
+ const ext = path25.extname(file3).toLowerCase();
27813
28208
  if (ext === ".mjs" || ext === ".js") return [process.execPath, [file3]];
27814
28209
  if (!isWin) return null;
27815
28210
  if (ext === ".ps1")
@@ -27817,18 +28212,18 @@ var commandFor = (file3) => {
27817
28212
  if (ext === ".cmd" || ext === ".bat") return [SYSTEM.cmd(), ["/d", "/c", file3]];
27818
28213
  return null;
27819
28214
  };
27820
- var BOOT = { root: path22.join(launchDir, "hooks"), cwd: workspace };
28215
+ var BOOT = { root: path25.join(launchDir, "hooks"), cwd: workspace };
27821
28216
  function projectHooks(name, cwd) {
27822
28217
  return {
27823
- root: path22.join(launchDir, "projects", name, "hooks"),
28218
+ root: path25.join(launchDir, "projects", name, "hooks"),
27824
28219
  cwd
27825
28220
  };
27826
28221
  }
27827
28222
  var hooksOf = (stage, target) => {
27828
- const dir = path22.join(target.root, stage);
28223
+ const dir = path25.join(target.root, stage);
27829
28224
  if (!exists(dir)) return [];
27830
- return fs16.readdirSync(dir).sort().flatMap((name) => {
27831
- const command = commandFor(path22.join(dir, name));
28225
+ return fs18.readdirSync(dir).sort().flatMap((name) => {
28226
+ const command = commandFor(path25.join(dir, name));
27832
28227
  return command ? [{ name, command }] : [];
27833
28228
  });
27834
28229
  };
@@ -27858,25 +28253,25 @@ async function runHooksAsync(stage, env, target) {
27858
28253
  }
27859
28254
 
27860
28255
  // src/guest/toolchains/tool-env.ts
27861
- import path23 from "node:path";
28256
+ import path26 from "node:path";
27862
28257
  function emptyEnv() {
27863
28258
  return { vars: {}, prepend: [], append: [], summary: [] };
27864
28259
  }
27865
28260
  var arch = process.arch === "arm64" ? "arm64" : "x64";
27866
28261
  function tool(...parts2) {
27867
- return path23.join(toolsDir, ...parts2);
28262
+ return path26.join(toolsDir, ...parts2);
27868
28263
  }
27869
28264
  function versionOf(exe, args = ["--version"], options = {}) {
27870
28265
  return /\d+\.\d+\.\d+\S*/.exec(execOutput(exe, args, options))?.[0] ?? "installed";
27871
28266
  }
27872
28267
 
27873
28268
  // src/guest/apps/app-installer.ts
27874
- import fs20 from "node:fs";
27875
- import path28 from "node:path";
28269
+ import fs22 from "node:fs";
28270
+ import path31 from "node:path";
27876
28271
 
27877
28272
  // src/guest/apps/after-install.ts
27878
- import fs17 from "node:fs";
27879
- import path24 from "node:path";
28273
+ import fs19 from "node:fs";
28274
+ import path27 from "node:path";
27880
28275
  var SYSINTERNALS_TOOLS = [
27881
28276
  "Process Explorer",
27882
28277
  "Process Monitor",
@@ -27897,16 +28292,16 @@ var SYSINTERNALS_TOOLS = [
27897
28292
  "ZoomIt"
27898
28293
  ];
27899
28294
  async function afterInstall(entry, exe) {
27900
- const dir = path24.dirname(exe);
28295
+ const dir = path27.dirname(exe);
27901
28296
  if (entry.needs?.includes("mesa")) {
27902
28297
  const mesa = tool("mesa", arch === "arm64" ? "arm64" : "x64");
27903
28298
  for (const dll of ["opengl32.dll", "libgallium_wgl.dll", "dxil.dll"]) {
27904
- if (exists(path24.join(mesa, dll)) && !exists(path24.join(dir, dll)))
27905
- fs17.copyFileSync(path24.join(mesa, dll), path24.join(dir, dll));
28299
+ if (exists(path27.join(mesa, dll)) && !exists(path27.join(dir, dll)))
28300
+ fs19.copyFileSync(path27.join(mesa, dll), path27.join(dir, dll));
27906
28301
  }
27907
28302
  }
27908
- if (entry.id === "godot" && !exists(path24.join(dir, "._sc_"))) fs17.writeFileSync(path24.join(dir, "._sc_"), "");
27909
- if (entry.id === "sublime") mkdirp(path24.join(dir, "Data"));
28303
+ if (entry.id === "godot" && !exists(path27.join(dir, "._sc_"))) fs19.writeFileSync(path27.join(dir, "._sc_"), "");
28304
+ if (entry.id === "sublime") mkdirp(path27.join(dir, "Data"));
27910
28305
  if (entry.id === "sysinternals") {
27911
28306
  for (const name of SYSINTERNALS_TOOLS) {
27912
28307
  await execAsync(
@@ -27919,14 +28314,14 @@ async function afterInstall(entry, exe) {
27919
28314
  }
27920
28315
 
27921
28316
  // src/guest/apps/find-exe.ts
27922
- import fs18 from "node:fs";
27923
- import path25 from "node:path";
28317
+ import fs20 from "node:fs";
28318
+ import path28 from "node:path";
27924
28319
  var MAX_DEPTH = 7;
27925
28320
  var MAX_ENTRIES = 5e4;
27926
28321
  var X64_FOLDER = /(^|[\\/])(amd64|x64|x86_64|win64)([\\/]|$)/i;
27927
28322
  function findExe(root, exe) {
27928
28323
  const match = exeMatcher(exe);
27929
- const best = (hits) => hits.find((h) => X64_FOLDER.test(path25.relative(root, h))) ?? hits[0] ?? null;
28324
+ const best = (hits) => hits.find((h) => X64_FOLDER.test(path28.relative(root, h))) ?? hits[0] ?? null;
27930
28325
  let queue = [root];
27931
28326
  let seen = 0;
27932
28327
  for (let depth = 0; depth < MAX_DEPTH && queue.length; depth++) {
@@ -27935,14 +28330,14 @@ function findExe(root, exe) {
27935
28330
  for (const dir of queue) {
27936
28331
  let entries2;
27937
28332
  try {
27938
- entries2 = fs18.readdirSync(dir, { withFileTypes: true });
28333
+ entries2 = fs20.readdirSync(dir, { withFileTypes: true });
27939
28334
  } catch {
27940
28335
  continue;
27941
28336
  }
27942
28337
  const hit = entries2.find((e) => e.isFile() && match(e.name));
27943
- if (hit) hits.push(path25.join(dir, hit.name));
28338
+ if (hit) hits.push(path28.join(dir, hit.name));
27944
28339
  else
27945
- next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path25.join(dir, e.name)));
28340
+ next.push(...entries2.filter((e) => e.isDirectory() && !e.isSymbolicLink()).map((e) => path28.join(dir, e.name)));
27946
28341
  if ((seen += entries2.length) > MAX_ENTRIES) return best(hits);
27947
28342
  }
27948
28343
  if (hits.length) return best(hits);
@@ -27953,12 +28348,12 @@ function findExe(root, exe) {
27953
28348
 
27954
28349
  // src/guest/apps/shortcuts.ts
27955
28350
  import os5 from "node:os";
27956
- import path26 from "node:path";
28351
+ import path29 from "node:path";
27957
28352
  function shortcuts(apps) {
27958
28353
  if (!apps.length) return;
27959
- const desktop = path26.join(os5.homedir(), "Desktop");
27960
- const start = path26.join(
27961
- process.env.APPDATA ?? path26.join(os5.homedir(), "AppData", "Roaming"),
28354
+ const desktop = path29.join(os5.homedir(), "Desktop");
28355
+ const start = path29.join(
28356
+ process.env.APPDATA ?? path29.join(os5.homedir(), "AppData", "Roaming"),
27962
28357
  "Microsoft",
27963
28358
  "Windows",
27964
28359
  "Start Menu",
@@ -27968,9 +28363,9 @@ function shortcuts(apps) {
27968
28363
  const links = apps.flatMap((app) => {
27969
28364
  const name = app.name.replace(/[\\/:*?"<>|]/g, "");
27970
28365
  return [desktop, start].map((folder) => ({
27971
- link: path26.join(folder, name + ".lnk"),
28366
+ link: path29.join(folder, name + ".lnk"),
27972
28367
  target: app.exe,
27973
- workingDirectory: path26.dirname(app.exe)
28368
+ workingDirectory: path29.dirname(app.exe)
27974
28369
  }));
27975
28370
  });
27976
28371
  runScriptWithJson("new-shortcuts.ps1", "ListFile", links);
@@ -28102,12 +28497,12 @@ async function resolve(entry) {
28102
28497
  }
28103
28498
 
28104
28499
  // src/guest/apps/unpack.ts
28105
- import fs19 from "node:fs";
28106
- import path27 from "node:path";
28500
+ import fs21 from "node:fs";
28501
+ import path30 from "node:path";
28107
28502
  var sevenZip = () => tool("apps", "7zip", "7z.exe");
28108
28503
  async function unpack(entry, file3, out, d) {
28109
28504
  if (entry.id === "7zip") {
28110
- const sevenZr = path27.join(path27.dirname(file3), "7zr.exe");
28505
+ const sevenZr = path30.join(path30.dirname(file3), "7zr.exe");
28111
28506
  const zr = await githubAsset("ip7z/7zip", /^7zr\.exe$/);
28112
28507
  await downloader.file(zr.url, sevenZr, zr.sha256);
28113
28508
  await execAsync(sevenZr, ["x", "-y", "-o" + out, file3], { stdio: "ignore" });
@@ -28116,17 +28511,17 @@ async function unpack(entry, file3, out, d) {
28116
28511
  switch (entry.unpack ?? "archive") {
28117
28512
  case "file": {
28118
28513
  mkdirp(out);
28119
- fs19.renameSync(file3, path27.join(out, /^\//.test(entry.exe) ? path27.basename(file3) : entry.exe));
28514
+ fs21.renameSync(file3, path30.join(out, /^\//.test(entry.exe) ? path30.basename(file3) : entry.exe));
28120
28515
  return;
28121
28516
  }
28122
28517
  case "nsis": {
28123
28518
  if (!exists(sevenZip()))
28124
28519
  throw new Error("7-Zip is needed to unpack " + entry.name + " and could not be installed");
28125
- const raw = path27.join(path27.dirname(out), "raw");
28520
+ const raw = path30.join(path30.dirname(out), "raw");
28126
28521
  await execAsync(sevenZip(), ["x", "-y", "-o" + raw, file3], { stdio: "ignore" });
28127
28522
  const inner = findExe(raw, "/^app-64\\.7z$/");
28128
28523
  if (inner) await execAsync(sevenZip(), ["x", "-y", "-o" + out, inner], { stdio: "ignore" });
28129
- else fs19.renameSync(raw, out);
28524
+ else fs21.renameSync(raw, out);
28130
28525
  return;
28131
28526
  }
28132
28527
  case "msi": {
@@ -28176,11 +28571,11 @@ var AppInstaller = class {
28176
28571
  async installOne(entry) {
28177
28572
  try {
28178
28573
  const dest = tool("apps", ...entry.id.split("/"));
28179
- if (!exists(path28.join(dest, MARKER)) || this.options.refresh) await this.download(entry, dest);
28574
+ if (!exists(path31.join(dest, MARKER)) || this.options.refresh) await this.download(entry, dest);
28180
28575
  const exe = findExe(dest, entry.exe);
28181
28576
  if (!exe) throw new Error(entry.exe + " not found in the download");
28182
28577
  await afterInstall(entry, exe);
28183
- if (entry.cli || entry.id === "sysinternals") this.env.prepend.push(path28.dirname(exe));
28578
+ if (entry.cli || entry.id === "sysinternals") this.env.prepend.push(path31.dirname(exe));
28184
28579
  if (!entry.cli) this.gui.push({ name: entry.name, exe });
28185
28580
  this.installed.push(entry.name);
28186
28581
  } catch (e) {
@@ -28193,10 +28588,10 @@ var AppInstaller = class {
28193
28588
  /** Downloads and unpacks one entry into its folder (replaced in one step: never half there). */
28194
28589
  async download(entry, dest) {
28195
28590
  const work = stagingFolder(dest);
28196
- const out = path28.join(work, "out");
28591
+ const out = path31.join(work, "out");
28197
28592
  try {
28198
28593
  if ("npm" in entry.source) {
28199
- const npmCli = path28.join(path28.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
28594
+ const npmCli = path31.join(path31.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
28200
28595
  log("Installing " + entry.name + " (npm) ...");
28201
28596
  await execAsync(process.execPath, [
28202
28597
  npmCli,
@@ -28211,14 +28606,14 @@ var AppInstaller = class {
28211
28606
  } else {
28212
28607
  const d = await resolve(entry);
28213
28608
  log("Downloading " + entry.name + " (" + d.fileName + ", ~" + entry.size + " once) ...");
28214
- const file3 = path28.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
28609
+ const file3 = path31.join(mkdirp(work), d.fileName.replace(/[\\/:*?"<>|]/g, "_"));
28215
28610
  await downloader.file(d.url, file3, { sha256: d.sha256 ?? null });
28216
28611
  await unpack(entry, file3, out, d);
28217
28612
  }
28218
- fs20.writeFileSync(path28.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
28613
+ fs22.writeFileSync(path31.join(out, MARKER), JSON.stringify({ id: entry.id, at: (/* @__PURE__ */ new Date()).toISOString() }));
28219
28614
  moveIntoPlace(out, dest);
28220
28615
  } finally {
28221
- safeRemove(work, path28.dirname(work));
28616
+ safeRemove(work, path31.dirname(work));
28222
28617
  }
28223
28618
  }
28224
28619
  };
@@ -28233,8 +28628,8 @@ async function setupApps(env, apps, o) {
28233
28628
  }
28234
28629
 
28235
28630
  // src/guest/toolchains/detect.ts
28236
- import fs21 from "node:fs";
28237
- import path29 from "node:path";
28631
+ import fs23 from "node:fs";
28632
+ import path32 from "node:path";
28238
28633
 
28239
28634
  // src/core/detect/versions.ts
28240
28635
  function pickNodeVersion(releases, spec) {
@@ -28366,14 +28761,14 @@ function workspaceEntries() {
28366
28761
  if (known) return known;
28367
28762
  const list = (dir) => {
28368
28763
  try {
28369
- return fs21.readdirSync(dir, { withFileTypes: true });
28764
+ return fs23.readdirSync(dir, { withFileTypes: true });
28370
28765
  } catch {
28371
28766
  return [];
28372
28767
  }
28373
28768
  };
28374
28769
  const top = list(workspace2);
28375
28770
  const below = top.filter((d) => d.isDirectory() && !d.name.startsWith(".") && !SKIP_DIRS.has(d.name.toLowerCase())).flatMap(
28376
- (d) => list(path29.join(workspace2, d.name)).filter((f) => f.isFile()).map((f) => d.name + "/" + f.name)
28771
+ (d) => list(path32.join(workspace2, d.name)).filter((f) => f.isFile()).map((f) => d.name + "/" + f.name)
28377
28772
  );
28378
28773
  const found = [...top.filter((d) => d.isFile()).map((d) => d.name), ...below];
28379
28774
  entries.set(workspace2.toLowerCase(), found);
@@ -28384,9 +28779,9 @@ function wanted(setting, toolchain) {
28384
28779
  }
28385
28780
  function versionFromFiles(files, parse5 = (t) => specFromVersionFile(t)) {
28386
28781
  for (const name of files) {
28387
- const file3 = path29.join(projectWorkspace(), name);
28782
+ const file3 = path32.join(projectWorkspace(), name);
28388
28783
  if (!exists(file3)) continue;
28389
- const spec = parse5(fs21.readFileSync(file3, "utf8"), name);
28784
+ const spec = parse5(fs23.readFileSync(file3, "utf8"), name);
28390
28785
  if (spec) return { spec, source: name };
28391
28786
  }
28392
28787
  return null;
@@ -28459,22 +28854,22 @@ var DatabaseServer = class {
28459
28854
  };
28460
28855
 
28461
28856
  // src/guest/databases/dynamodb.ts
28462
- import fs26 from "node:fs";
28463
- import path32 from "node:path";
28857
+ import fs28 from "node:fs";
28858
+ import path35 from "node:path";
28464
28859
  import { spawn as spawn3 } from "node:child_process";
28465
28860
 
28466
28861
  // src/guest/toolchains/languages/java.ts
28467
- import fs24 from "node:fs";
28468
- import path30 from "node:path";
28862
+ import fs26 from "node:fs";
28863
+ import path33 from "node:path";
28469
28864
 
28470
28865
  // src/guest/toolchains/version-cache.ts
28471
- import fs23 from "node:fs";
28866
+ import fs25 from "node:fs";
28472
28867
 
28473
28868
  // src/guest/toolchains/state-file.ts
28474
- import fs22 from "node:fs";
28869
+ import fs24 from "node:fs";
28475
28870
  function readState(file3, schema, empty) {
28476
28871
  try {
28477
- return schema.safeParse(JSON.parse(fs22.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
28872
+ return schema.safeParse(JSON.parse(fs24.readFileSync(file3, "utf8").replace(/^\uFEFF/, ""))).data ?? empty;
28478
28873
  } catch {
28479
28874
  return empty;
28480
28875
  }
@@ -28509,7 +28904,7 @@ var VersionCache = class {
28509
28904
  return cached2.value;
28510
28905
  try {
28511
28906
  const value = await resolve2();
28512
- fs23.mkdirSync(toolsDir, { recursive: true });
28907
+ fs25.mkdirSync(toolsDir, { recursive: true });
28513
28908
  writeJsonAtomic(this.file(), { ...this.remembered(), [key]: { value, at: Date.now() } });
28514
28909
  return value;
28515
28910
  } catch (e) {
@@ -28562,7 +28957,7 @@ var setupJdk = async (env, config2) => {
28562
28957
  const { major, source } = await javaMajor(config2);
28563
28958
  const release = await resolveCached("java:" + major, async () => (await temurin(major)).release_name);
28564
28959
  const home = tool("java", release.replace(/[^A-Za-z0-9.-]/g, "_"));
28565
- if (!exists(path30.join(home, "bin", "java.exe"))) {
28960
+ if (!exists(path33.join(home, "bin", "java.exe"))) {
28566
28961
  const asset = await temurin(major);
28567
28962
  log("Downloading Java " + release + " (JDK, ~200 MB once) ...");
28568
28963
  await downloader.archive(asset.binary.package.link, home, {
@@ -28572,13 +28967,13 @@ var setupJdk = async (env, config2) => {
28572
28967
  });
28573
28968
  }
28574
28969
  env.vars.JAVA_HOME = home;
28575
- env.prepend.push(path30.join(home, "bin"));
28970
+ env.prepend.push(path33.join(home, "bin"));
28576
28971
  env.summary.push("java: " + release + " (Temurin, from " + source + ")");
28577
28972
  };
28578
28973
  async function ensureJdk() {
28579
28974
  const root = tool("java");
28580
- const installed = exists(root) ? fs24.readdirSync(root).filter((d) => exists(path30.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
28581
- if (installed.length) return path30.join(root, installed[0]);
28975
+ const installed = exists(root) ? fs26.readdirSync(root).filter((d) => exists(path33.join(root, d, "bin", "java.exe"))).sort((a, b) => b.localeCompare(a, void 0, { numeric: true })) : [];
28976
+ if (installed.length) return path33.join(root, installed[0]);
28582
28977
  const scratch = emptyEnv();
28583
28978
  await setupJdk(scratch, { enabled: true, version: "lts", maven: false, gradle: false });
28584
28979
  return scratch.vars.JAVA_HOME;
@@ -28591,7 +28986,7 @@ var setupMaven = async (env) => {
28591
28986
  return pickPackageVersion(versions, "3") ?? Promise.reject(new Error("No Maven 3 release found"));
28592
28987
  });
28593
28988
  const home = tool("maven", version2);
28594
- if (!exists(path30.join(home, "bin", "mvn.cmd"))) {
28989
+ if (!exists(path33.join(home, "bin", "mvn.cmd"))) {
28595
28990
  const url2 = MAVEN + version2 + "/apache-maven-" + version2 + "-bin.zip";
28596
28991
  log("Downloading Maven " + version2 + " (~10 MB once) ...");
28597
28992
  await downloader.archive(url2, home, {
@@ -28601,7 +28996,7 @@ var setupMaven = async (env) => {
28601
28996
  }
28602
28997
  const repo = tool("maven-repository");
28603
28998
  Object.assign(env.vars, { MAVEN_HOME: home, M2_HOME: home, MAVEN_OPTS: "-Dmaven.repo.local=" + repo });
28604
- env.prepend.push(path30.join(home, "bin"));
28999
+ env.prepend.push(path33.join(home, "bin"));
28605
29000
  env.summary.push("maven: " + version2);
28606
29001
  };
28607
29002
  var setupGradle = async (env) => {
@@ -28613,7 +29008,7 @@ var setupGradle = async (env) => {
28613
29008
  async () => current?.version ?? Promise.reject(new Error("Gradle version lookup failed"))
28614
29009
  );
28615
29010
  const home = tool("gradle", version2);
28616
- if (!exists(path30.join(home, "bin", "gradle.bat"))) {
29011
+ if (!exists(path33.join(home, "bin", "gradle.bat"))) {
28617
29012
  if (!current || current.version !== version2)
28618
29013
  throw new Error("Gradle " + version2 + " is not installed and cannot be downloaded right now");
28619
29014
  log("Downloading Gradle " + version2 + " (~130 MB once) ...");
@@ -28624,13 +29019,13 @@ var setupGradle = async (env) => {
28624
29019
  });
28625
29020
  }
28626
29021
  const userHome = tool("gradle-home");
28627
- fs24.mkdirSync(userHome, { recursive: true });
29022
+ fs26.mkdirSync(userHome, { recursive: true });
28628
29023
  Object.assign(env.vars, {
28629
29024
  GRADLE_HOME: home,
28630
29025
  GRADLE_USER_HOME: userHome,
28631
29026
  GRADLE_OPTS: "-Dorg.gradle.vfs.watch=false"
28632
29027
  });
28633
- env.prepend.push(path30.join(home, "bin"));
29028
+ env.prepend.push(path33.join(home, "bin"));
28634
29029
  env.summary.push("gradle: " + version2);
28635
29030
  };
28636
29031
  async function setupJava(env, config2) {
@@ -28654,29 +29049,29 @@ async function setupJava(env, config2) {
28654
29049
  }
28655
29050
 
28656
29051
  // src/guest/databases/server.ts
28657
- import fs25 from "node:fs";
28658
- import path31 from "node:path";
29052
+ import fs27 from "node:fs";
29053
+ import path34 from "node:path";
28659
29054
  import { spawn as spawn2 } from "node:child_process";
28660
29055
  function dataFor(name) {
28661
- return path31.join(dataDir, "databases", name);
29056
+ return path34.join(dataDir, "databases", name);
28662
29057
  }
28663
29058
  async function startServer(name, exe, args, port) {
28664
29059
  if (await portOpen(port)) throw new Error("port " + port + " is already in use (change databases." + name + ".port)");
28665
- const logFile2 = path31.join(logsDir, name + ".log");
28666
- const out = fs25.openSync(logFile2, "a");
29060
+ const logFile2 = path34.join(logsDir, name + ".log");
29061
+ const out = fs27.openSync(logFile2, "a");
28667
29062
  spawn2(exe, args, { detached: true, stdio: ["ignore", out, out], windowsHide: true }).unref();
28668
- fs25.closeSync(out);
29063
+ fs27.closeSync(out);
28669
29064
  if (!await waitForPort(port, 60))
28670
29065
  throw new Error(name + " did not start listening on port " + port + "; see " + logFile2);
28671
29066
  }
28672
29067
  async function clearStaleLocks(dir, files, port) {
28673
29068
  if (await portOpen(port)) return;
28674
- for (const f of files) fs25.rmSync(path31.join(dir, f), { force: true });
29069
+ for (const f of files) fs27.rmSync(path34.join(dir, f), { force: true });
28675
29070
  }
28676
29071
  async function createOnce(data, marker, create) {
28677
- if (exists(path31.join(data, marker))) return;
29072
+ if (exists(path34.join(data, marker))) return;
28678
29073
  const existed = exists(data);
28679
- mkdirp(path31.dirname(data));
29074
+ mkdirp(path34.dirname(data));
28680
29075
  try {
28681
29076
  await create();
28682
29077
  } catch (e) {
@@ -28700,9 +29095,9 @@ var DynamoServer = class extends DatabaseServer {
28700
29095
  * local endpoint up from AWS_ENDPOINT_URL_DYNAMODB, with dummy credentials (real ones never reach the sandbox).
28701
29096
  */
28702
29097
  async start(env, plan2) {
28703
- const java = path32.join(await ensureJdk(), "bin", "java.exe");
29098
+ const java = path35.join(await ensureJdk(), "bin", "java.exe");
28704
29099
  const home = tool("dynamodb-local");
28705
- if (!exists(path32.join(home, "DynamoDBLocal.jar"))) {
29100
+ if (!exists(path35.join(home, "DynamoDBLocal.jar"))) {
28706
29101
  log("Downloading DynamoDB Local (~60 MB once) ...");
28707
29102
  const sha256 = (await fetchText(DYNAMO_ZIP + ".sha256")).trim().split(/\s+/)[0];
28708
29103
  await downloader.archive(DYNAMO_ZIP, home, {
@@ -28716,9 +29111,9 @@ var DynamoServer = class extends DatabaseServer {
28716
29111
  "dynamodb",
28717
29112
  java,
28718
29113
  [
28719
- "-Djava.library.path=" + path32.join(home, "DynamoDBLocal_lib"),
29114
+ "-Djava.library.path=" + path35.join(home, "DynamoDBLocal_lib"),
28720
29115
  "-jar",
28721
- path32.join(home, "DynamoDBLocal.jar"),
29116
+ path35.join(home, "DynamoDBLocal.jar"),
28722
29117
  "-sharedDb",
28723
29118
  "-dbPath",
28724
29119
  data,
@@ -28742,10 +29137,10 @@ var DynamoServer = class extends DatabaseServer {
28742
29137
  );
28743
29138
  if (!plan2.adminPort) return;
28744
29139
  const prefix = tool("dynamodb-admin");
28745
- const script = path32.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
29140
+ const script = path35.join(prefix, "node_modules", "dynamodb-admin", "dist", "dynamodb-admin.js");
28746
29141
  if (!exists(script)) {
28747
29142
  log("Installing dynamodb-admin, the DynamoDB web UI (~20 MB once) ...");
28748
- const npmCli = path32.join(path32.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
29143
+ const npmCli = path35.join(path35.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
28749
29144
  await execAsync(
28750
29145
  process.execPath,
28751
29146
  [npmCli, "install", "--global", "--prefix", prefix, "dynamodb-admin", "--no-fund", "--no-audit"],
@@ -28758,15 +29153,15 @@ var DynamoServer = class extends DatabaseServer {
28758
29153
  );
28759
29154
  return;
28760
29155
  }
28761
- const out = fs26.openSync(path32.join(logsDir, "dynamodb-admin.log"), "a");
29156
+ const out = fs28.openSync(path35.join(logsDir, "dynamodb-admin.log"), "a");
28762
29157
  spawn3(
28763
29158
  process.execPath,
28764
29159
  [script, "--port", String(plan2.adminPort), "--dynamo-endpoint", endpoint, "--skip-default-credentials"],
28765
29160
  { detached: true, stdio: ["ignore", out, out], windowsHide: true, env: { ...process.env, ...aws } }
28766
29161
  ).unref();
28767
- fs26.closeSync(out);
29162
+ fs28.closeSync(out);
28768
29163
  if (!await waitForPort(plan2.adminPort, 30))
28769
- throw new Error("dynamodb-admin did not start; see " + path32.join(logsDir, "dynamodb-admin.log"));
29164
+ throw new Error("dynamodb-admin did not start; see " + path35.join(logsDir, "dynamodb-admin.log"));
28770
29165
  env.summary.push(
28771
29166
  "dynamodb-admin: http://localhost:" + plan2.adminPort + " (browse and edit tables in the sandbox's browser)"
28772
29167
  );
@@ -28774,18 +29169,18 @@ var DynamoServer = class extends DatabaseServer {
28774
29169
  };
28775
29170
 
28776
29171
  // src/guest/databases/mongodb.ts
28777
- import path33 from "node:path";
29172
+ import path36 from "node:path";
28778
29173
 
28779
29174
  // src/guest/toolchains/install.ts
28780
- import fs27 from "node:fs";
29175
+ import fs29 from "node:fs";
28781
29176
  async function downloadFile(url2, file3, sha256 = null) {
28782
29177
  const part = file3 + ".part";
28783
29178
  try {
28784
29179
  await downloader.file(url2, part, sha256);
28785
- fs27.rmSync(file3, { force: true });
28786
- fs27.renameSync(part, file3);
29180
+ fs29.rmSync(file3, { force: true });
29181
+ fs29.renameSync(part, file3);
28787
29182
  } finally {
28788
- fs27.rmSync(part, { force: true });
29183
+ fs29.rmSync(part, { force: true });
28789
29184
  }
28790
29185
  }
28791
29186
  async function installFromGithub(repo, pattern, o) {
@@ -28814,13 +29209,13 @@ var MongoServer = class extends DatabaseServer {
28814
29209
  };
28815
29210
  const version2 = await resolveCached("mongodb:" + plan2.version, async () => (await find()).version);
28816
29211
  const home = tool("mongodb", version2);
28817
- if (!exists(path33.join(home, "bin", "mongod.exe"))) {
29212
+ if (!exists(path36.join(home, "bin", "mongod.exe"))) {
28818
29213
  const { archive } = await find();
28819
29214
  log("Downloading MongoDB " + version2 + " (~400 MB once) ...");
28820
29215
  await downloader.archive(archive.url, home, { sha256: archive.sha256, locate: "mongod.exe", up: 1 });
28821
29216
  }
28822
29217
  const shell = tool("mongosh");
28823
- if (!exists(path33.join(shell, "mongosh.exe"))) {
29218
+ if (!exists(path36.join(shell, "mongosh.exe"))) {
28824
29219
  await installFromGithub("mongodb-js/mongosh", /^mongosh-[\d.]+-win32-x64\.zip$/, {
28825
29220
  dest: shell,
28826
29221
  what: "mongosh, the MongoDB shell (~50 MB once)",
@@ -28831,17 +29226,17 @@ var MongoServer = class extends DatabaseServer {
28831
29226
  await clearStaleLocks(data, ["mongod.lock"], plan2.port);
28832
29227
  await startServer(
28833
29228
  "mongodb",
28834
- path33.join(home, "bin", "mongod.exe"),
29229
+ path36.join(home, "bin", "mongod.exe"),
28835
29230
  ["--dbpath", data, "--bind_ip", "127.0.0.1", "--port", String(plan2.port)],
28836
29231
  plan2.port
28837
29232
  );
28838
- env.prepend.push(path33.join(home, "bin"), shell);
29233
+ env.prepend.push(path36.join(home, "bin"), shell);
28839
29234
  env.summary.push("mongodb " + version2 + ": mongodb://127.0.0.1:" + plan2.port + " (mongosh on PATH)");
28840
29235
  }
28841
29236
  };
28842
29237
 
28843
29238
  // src/guest/databases/mysql.ts
28844
- import path34 from "node:path";
29239
+ import path37 from "node:path";
28845
29240
  var MARIA = "https://downloads.mariadb.org/rest-api/mariadb/";
28846
29241
  var MysqlServer = class extends DatabaseServer {
28847
29242
  id = "mysql";
@@ -28859,8 +29254,8 @@ var MysqlServer = class extends DatabaseServer {
28859
29254
  };
28860
29255
  const version2 = await resolveCached("mariadb-version:" + series, async () => (await latest()).version);
28861
29256
  const home = tool("mariadb", version2);
28862
- const bin = path34.join(home, "bin");
28863
- if (!exists(path34.join(bin, "mariadbd.exe"))) {
29257
+ const bin = path37.join(home, "bin");
29258
+ if (!exists(path37.join(bin, "mariadbd.exe"))) {
28864
29259
  const { zip } = await latest();
28865
29260
  log("Downloading MariaDB " + version2 + " (~90 MB once) ...");
28866
29261
  await downloader.archive(zip.file_download_url.replace(/^http:/, "https:"), home, {
@@ -28873,13 +29268,13 @@ var MysqlServer = class extends DatabaseServer {
28873
29268
  const data = dataFor("mariadb");
28874
29269
  await createOnce(data, "mysql", async () => {
28875
29270
  log("Creating the MariaDB database (first start) ...");
28876
- await execAsync(path34.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], {
29271
+ await execAsync(path37.join(bin, "mariadb-install-db.exe"), ["--datadir=" + data, "--port=" + plan2.port], {
28877
29272
  stdio: "ignore"
28878
29273
  });
28879
29274
  });
28880
29275
  await startServer(
28881
29276
  "mysql",
28882
- path34.join(bin, "mariadbd.exe"),
29277
+ path37.join(bin, "mariadbd.exe"),
28883
29278
  ["--datadir=" + data, "--port=" + plan2.port, "--bind-address=127.0.0.1", "--console"],
28884
29279
  plan2.port
28885
29280
  );
@@ -28892,8 +29287,8 @@ var MysqlServer = class extends DatabaseServer {
28892
29287
  };
28893
29288
 
28894
29289
  // src/guest/databases/postgres.ts
28895
- import fs28 from "node:fs";
28896
- import path35 from "node:path";
29290
+ import fs30 from "node:fs";
29291
+ import path38 from "node:path";
28897
29292
  function postgresData(version2) {
28898
29293
  return dataFor("postgres-" + version2.split(".")[0]);
28899
29294
  }
@@ -28908,8 +29303,8 @@ var PostgresServer = class extends DatabaseServer {
28908
29303
  return hit ? hit.major + "." + hit.latestMinor : Promise.reject(new Error("No supported PostgreSQL " + plan2.version));
28909
29304
  });
28910
29305
  const home = tool("postgres", exact);
28911
- const bin = path35.join(home, "bin");
28912
- if (!exists(path35.join(bin, "pg_ctl.exe"))) {
29306
+ const bin = path38.join(home, "bin");
29307
+ if (!exists(path38.join(bin, "pg_ctl.exe"))) {
28913
29308
  log("Downloading PostgreSQL " + exact + " (~330 MB once) ...");
28914
29309
  await downloader.archive(
28915
29310
  "https://get.enterprisedb.com/postgresql/postgresql-" + exact + "-1-windows-x64-binaries.zip",
@@ -28926,7 +29321,7 @@ var PostgresServer = class extends DatabaseServer {
28926
29321
  await createOnce(data, "PG_VERSION", async () => {
28927
29322
  log("Creating the PostgreSQL database (first start) ...");
28928
29323
  await execAsync(
28929
- path35.join(bin, "initdb.exe"),
29324
+ path38.join(bin, "initdb.exe"),
28930
29325
  ["-D", data, "-U", "postgres", "-A", "trust", "-E", "UTF8", "--locale=C"],
28931
29326
  { stdio: "ignore" }
28932
29327
  );
@@ -28935,7 +29330,7 @@ var PostgresServer = class extends DatabaseServer {
28935
29330
  throw new Error("port " + plan2.port + " is already in use (change databases.postgres.port)");
28936
29331
  await clearStaleLocks(data, ["postmaster.pid"], plan2.port);
28937
29332
  await execAsync(
28938
- path35.join(bin, "pg_ctl.exe"),
29333
+ path38.join(bin, "pg_ctl.exe"),
28939
29334
  [
28940
29335
  "start",
28941
29336
  "-D",
@@ -28944,7 +29339,7 @@ var PostgresServer = class extends DatabaseServer {
28944
29339
  "-t",
28945
29340
  "60",
28946
29341
  "-l",
28947
- path35.join(logsDir, "postgres.log"),
29342
+ path38.join(logsDir, "postgres.log"),
28948
29343
  "-o",
28949
29344
  "-p " + plan2.port + " -c listen_addresses=localhost"
28950
29345
  ],
@@ -28959,10 +29354,10 @@ var PostgresServer = class extends DatabaseServer {
28959
29354
  /** Every installed version's cluster shuts down cleanly through pg_ctl first. */
28960
29355
  async stop(plan2) {
28961
29356
  if (exists(tool("postgres"))) {
28962
- for (const version2 of fs28.readdirSync(tool("postgres"))) {
29357
+ for (const version2 of fs30.readdirSync(tool("postgres"))) {
28963
29358
  const data = postgresData(version2);
28964
- const pgCtl = path35.join(tool("postgres", version2), "bin", "pg_ctl.exe");
28965
- if (exists(path35.join(data, "postmaster.pid")) && exists(pgCtl))
29359
+ const pgCtl = path38.join(tool("postgres", version2), "bin", "pg_ctl.exe");
29360
+ if (exists(path38.join(data, "postmaster.pid")) && exists(pgCtl))
28966
29361
  await execAsync(pgCtl, ["stop", "-D", data, "-m", "fast", "-w"], { stdio: "ignore" });
28967
29362
  }
28968
29363
  }
@@ -28971,12 +29366,12 @@ var PostgresServer = class extends DatabaseServer {
28971
29366
  };
28972
29367
 
28973
29368
  // src/guest/databases/redis.ts
28974
- import path36 from "node:path";
29369
+ import path39 from "node:path";
28975
29370
  var RedisServer = class extends DatabaseServer {
28976
29371
  id = "redis";
28977
29372
  async start(env, plan2) {
28978
29373
  const home = tool("redis");
28979
- if (!exists(path36.join(home, "redis-server.exe"))) {
29374
+ if (!exists(path39.join(home, "redis-server.exe"))) {
28980
29375
  await installFromGithub("redis-windows/redis-windows", /^Redis-[\d.]+-Windows-x64-msys2\.zip$/, {
28981
29376
  dest: home,
28982
29377
  what: (a) => "Redis (" + a.name + ", ~10 MB once)",
@@ -28986,7 +29381,7 @@ var RedisServer = class extends DatabaseServer {
28986
29381
  const data = mkdirp(dataFor("redis"));
28987
29382
  await startServer(
28988
29383
  "redis",
28989
- path36.join(home, "redis-server.exe"),
29384
+ path39.join(home, "redis-server.exe"),
28990
29385
  ["--port", String(plan2.port), "--bind", "127.0.0.1", "--dir", data.replace(/\\/g, "/"), "--appendonly", "yes"],
28991
29386
  plan2.port
28992
29387
  );
@@ -29024,36 +29419,37 @@ async function setupDatabase(env, plan2) {
29024
29419
  }
29025
29420
 
29026
29421
  // src/guest/toolchains/tools/git.ts
29027
- import fs30 from "node:fs";
29028
- import path38 from "node:path";
29422
+ import fs32 from "node:fs";
29423
+ import path41 from "node:path";
29029
29424
 
29030
29425
  // src/guest/runtime/csc.ts
29031
- import fs29 from "node:fs";
29426
+ import fs31 from "node:fs";
29032
29427
  import os6 from "node:os";
29033
- import path37 from "node:path";
29428
+ import path40 from "node:path";
29034
29429
  import crypto3 from "node:crypto";
29035
29430
  import { spawnSync as spawnSync5 } from "node:child_process";
29036
- var CSC = path37.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
29431
+ var CSC = path40.join(process.env.WINDIR ?? "C:\\Windows", "Microsoft.NET", "Framework64", "v4.0.30319", "csc.exe");
29037
29432
  var SOURCES = {
29038
29433
  ptyhost: "PtyHost.cs",
29039
29434
  gitshim: "GitShim.cs",
29040
29435
  vswhere: "VsWhere.cs",
29041
29436
  openssl: "OpenSsl.cs",
29042
29437
  cargoshim: "CargoShim.cs",
29043
- linkgate: "LinkGate.cs"
29438
+ linkgate: "LinkGate.cs",
29439
+ pathsync: "PathSync.cs"
29044
29440
  };
29045
29441
  function sourceOf(name) {
29046
- return path37.join(launchDir, "sandbox", "csharp", SOURCES[name]);
29442
+ return path40.join(launchDir, "sandbox", "csharp", SOURCES[name]);
29047
29443
  }
29048
29444
  function sourceHash(name) {
29049
- return crypto3.createHash("sha256").update(fs29.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
29445
+ return crypto3.createHash("sha256").update(fs31.readFileSync(sourceOf(name))).digest("hex").slice(0, 12);
29050
29446
  }
29051
29447
  function ensureCompiled(name) {
29052
- const exe = path37.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
29448
+ const exe = path40.join(os6.tmpdir(), "agent-sandbox", name + "-" + sourceHash(name) + ".exe");
29053
29449
  if (exists(exe)) return exe;
29054
29450
  if (!exists(CSC))
29055
29451
  throw new Error("The .NET Framework C# compiler was not found at " + CSC + " (it ships with Windows 10/11).");
29056
- mkdirp(path37.dirname(exe));
29452
+ mkdirp(path40.dirname(exe));
29057
29453
  const result = spawnSync5(CSC, ["/nologo", "/optimize", "/target:exe", "/out:" + exe, sourceOf(name)], {
29058
29454
  encoding: "utf8",
29059
29455
  windowsHide: true
@@ -29087,23 +29483,23 @@ var installPortableGit = async (root) => {
29087
29483
  await downloader.file(asset.url, sfx, asset.sha256);
29088
29484
  await execAsync(sfx, ["-o" + root, "-y"], { stdio: "ignore" });
29089
29485
  } finally {
29090
- fs30.rmSync(sfx, { force: true });
29486
+ fs32.rmSync(sfx, { force: true });
29091
29487
  }
29092
29488
  };
29093
29489
  var installGuard = (env, access, realGit) => {
29094
29490
  const dir = mkdirp(tool("gitguard"));
29095
- const guard = path38.join(launchDir, "runtime", "gitguard.js");
29096
- if (duringSession() && (exists(path38.join(dir, "git.exe")) || exists(path38.join(dir, "git.cmd")))) {
29491
+ const guard = path41.join(launchDir, "runtime", "gitguard.js");
29492
+ if (duringSession() && (exists(path41.join(dir, "git.exe")) || exists(path41.join(dir, "git.cmd")))) {
29097
29493
  } else
29098
29494
  try {
29099
- fs30.copyFileSync(ensureCompiled("gitshim"), path38.join(dir, "git.exe"));
29100
- fs30.rmSync(path38.join(dir, "git.cmd"), { force: true });
29495
+ fs32.copyFileSync(ensureCompiled("gitshim"), path41.join(dir, "git.exe"));
29496
+ fs32.rmSync(path41.join(dir, "git.cmd"), { force: true });
29101
29497
  } catch (e) {
29102
29498
  warn("git guard: falling back to git.cmd (" + errMsg(e) + ")");
29103
- fs30.writeFileSync(path38.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
29499
+ fs32.writeFileSync(path41.join(dir, "git.cmd"), '@"' + process.execPath + '" "' + guard + '" %*\r\n');
29104
29500
  }
29105
- fs30.writeFileSync(
29106
- path38.join(dir, "bashenv.sh"),
29501
+ fs32.writeFileSync(
29502
+ path41.join(dir, "bashenv.sh"),
29107
29503
  'git() { "' + posix(process.execPath) + '" "' + posix(guard) + '" "$@"; }\nexport -f git\n'
29108
29504
  );
29109
29505
  env.prepend.unshift(dir);
@@ -29112,13 +29508,13 @@ var installGuard = (env, access, realGit) => {
29112
29508
  AGENT_REAL_GIT: access === "readonly" ? realGit : "",
29113
29509
  AGENT_GUARD_NODE: process.execPath,
29114
29510
  AGENT_GUARD_SCRIPT: guard,
29115
- BASH_ENV: posix(path38.join(dir, "bashenv.sh"))
29511
+ BASH_ENV: posix(path41.join(dir, "bashenv.sh"))
29116
29512
  });
29117
29513
  if (access === "readonly") {
29118
- const hooks = mkdirp(path38.join(dir, "hooks"));
29514
+ const hooks = mkdirp(path41.join(dir, "hooks"));
29119
29515
  for (const hook of BLOCKED_HOOKS)
29120
- fs30.writeFileSync(
29121
- path38.join(hooks, hook),
29516
+ fs32.writeFileSync(
29517
+ path41.join(hooks, hook),
29122
29518
  '#!/bin/sh\necho "git is read-only in this sandbox: ' + hook + ' refused." >&2\nexit 1\n'
29123
29519
  );
29124
29520
  Object.assign(env.vars, {
@@ -29127,22 +29523,22 @@ var installGuard = (env, access, realGit) => {
29127
29523
  GIT_CONFIG_VALUE_0: posix(hooks)
29128
29524
  });
29129
29525
  } else {
29130
- env.vars.GIT_DIR = path38.join(dataDir, "git-disabled");
29526
+ env.vars.GIT_DIR = path41.join(dataDir, "git-disabled");
29131
29527
  }
29132
29528
  };
29133
29529
  var pointAtOwnCertificates = (root) => {
29134
- const config2 = path38.join(root, "etc", "gitconfig");
29135
- const bundle = path38.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
29530
+ const config2 = path41.join(root, "etc", "gitconfig");
29531
+ const bundle = path41.join(root, "mingw64", "etc", "ssl", "certs", "ca-bundle.crt");
29136
29532
  if (!exists(config2) || !exists(bundle)) return;
29137
- const text = fs30.readFileSync(config2, "utf8");
29533
+ const text = fs32.readFileSync(config2, "utf8");
29138
29534
  const fixed = text.replace(/^(\s*sslCAInfo\s*=\s*).*$/gim, (_m, key) => key + posix(bundle));
29139
- if (fixed !== text) fs30.writeFileSync(config2, fixed);
29535
+ if (fixed !== text) fs32.writeFileSync(config2, fixed);
29140
29536
  };
29141
29537
  async function setupGit(env, hostCopy, refresh, access) {
29142
29538
  const root = tool("git");
29143
- const bash = path38.join(root, "bin", "bash.exe");
29144
- const gitExe = path38.join(root, "cmd", "git.exe");
29145
- const hostGit = path38.join(hostToolsDir, "git");
29539
+ const bash = path41.join(root, "bin", "bash.exe");
29540
+ const gitExe = path41.join(root, "cmd", "git.exe");
29541
+ const hostGit = path41.join(hostToolsDir, "git");
29146
29542
  if (exists(root) && !exists(bash)) {
29147
29543
  log("Replacing the old MinGit (no bash) with full Git for Windows.");
29148
29544
  safeRemove(root, toolsDir);
@@ -29156,11 +29552,11 @@ async function setupGit(env, hostCopy, refresh, access) {
29156
29552
  }
29157
29553
  const work = stagingFolder(root);
29158
29554
  try {
29159
- if (hostCopy && exists(path38.join(hostGit, "bin", "bash.exe"))) {
29555
+ if (hostCopy && exists(path41.join(hostGit, "bin", "bash.exe"))) {
29160
29556
  log("Copying Git for Windows from this PC ...");
29161
29557
  robocopy(hostGit, work);
29162
29558
  } else await installPortableGit(work);
29163
- if (!exists(path38.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
29559
+ if (!exists(path41.join(work, "bin", "bash.exe"))) throw new Error("bash.exe missing after installing Git");
29164
29560
  moveIntoPlace(work, root);
29165
29561
  } finally {
29166
29562
  safeRemove(work, toolsDir);
@@ -29169,10 +29565,10 @@ async function setupGit(env, hostCopy, refresh, access) {
29169
29565
  if (!exists(bash)) throw new Error("bash.exe missing after installing Git");
29170
29566
  pointAtOwnCertificates(root);
29171
29567
  env.vars.CLAUDE_CODE_GIT_BASH_PATH = bash;
29172
- env.append.push(path38.join(root, "usr", "bin"));
29568
+ env.append.push(path41.join(root, "usr", "bin"));
29173
29569
  const version2 = execOutput(gitExe, ["--version"]).replace(/^git version /, "");
29174
29570
  if (access === "full") {
29175
- env.prepend.push(path38.join(root, "cmd"));
29571
+ env.prepend.push(path41.join(root, "cmd"));
29176
29572
  env.summary.push("git: " + version2);
29177
29573
  return;
29178
29574
  }
@@ -29183,8 +29579,8 @@ async function setupGit(env, hostCopy, refresh, access) {
29183
29579
  }
29184
29580
 
29185
29581
  // src/guest/toolchains/languages/go.ts
29186
- import fs31 from "node:fs";
29187
- import path39 from "node:path";
29582
+ import fs33 from "node:fs";
29583
+ import path42 from "node:path";
29188
29584
 
29189
29585
  // src/guest/toolchains/package-ledger.ts
29190
29586
  var LedgerSchema = external_exports.record(external_exports.string(), external_exports.string());
@@ -29238,7 +29634,7 @@ async function setupGo(env, config2) {
29238
29634
  }
29239
29635
  const version2 = await resolveCached("go:" + config2.version, async () => (await findRelease(config2.version)).version);
29240
29636
  const root = tool("go", version2);
29241
- if (!exists(path39.join(root, "bin", "go.exe"))) {
29637
+ if (!exists(path42.join(root, "bin", "go.exe"))) {
29242
29638
  const goArch = arch === "arm64" ? "arm64" : "amd64";
29243
29639
  const file3 = (await findRelease(version2)).files.find(
29244
29640
  (f) => f.os === "windows" && f.arch === goArch && f.kind === "archive"
@@ -29255,16 +29651,16 @@ async function setupGo(env, config2) {
29255
29651
  const vars = {
29256
29652
  GOROOT: root,
29257
29653
  GOPATH,
29258
- GOBIN: path39.join(GOPATH, "bin"),
29259
- GOMODCACHE: path39.join(GOPATH, "pkg", "mod"),
29654
+ GOBIN: path42.join(GOPATH, "bin"),
29655
+ GOMODCACHE: path42.join(GOPATH, "pkg", "mod"),
29260
29656
  GOCACHE: tool("go-cache"),
29261
29657
  GOTOOLCHAIN: "auto",
29262
29658
  GOTELEMETRY: "off"
29263
29659
  };
29264
- fs31.mkdirSync(vars.GOBIN, { recursive: true });
29660
+ fs33.mkdirSync(vars.GOBIN, { recursive: true });
29265
29661
  Object.assign(env.vars, vars);
29266
- env.prepend.push(path39.join(root, "bin"), vars.GOBIN);
29267
- const go = path39.join(root, "bin", "go.exe");
29662
+ env.prepend.push(path42.join(root, "bin"), vars.GOBIN);
29663
+ const go = path42.join(root, "bin", "go.exe");
29268
29664
  env.summary.push("go: " + versionOf(go, ["version"]));
29269
29665
  await installOnce(
29270
29666
  env,
@@ -29275,8 +29671,8 @@ async function setupGo(env, config2) {
29275
29671
  }
29276
29672
 
29277
29673
  // src/guest/toolchains/tools/cli.ts
29278
- import fs32 from "node:fs";
29279
- import path41 from "node:path";
29674
+ import fs34 from "node:fs";
29675
+ import path44 from "node:path";
29280
29676
 
29281
29677
  // src/guest/toolchains/catalogue.ts
29282
29678
  function pwshAsset(arch2) {
@@ -29323,14 +29719,14 @@ function decideCli(settings, ctx) {
29323
29719
  }
29324
29720
 
29325
29721
  // src/guest/toolchains/runtimes.ts
29326
- import path40 from "node:path";
29722
+ import path43 from "node:path";
29327
29723
  async function setupSingleExe(env, name, repo, pattern, exeName, dir, options = {}) {
29328
29724
  if (dryRun) {
29329
29725
  log("(dry run) would provision " + name);
29330
29726
  return;
29331
29727
  }
29332
- const bin = options.subdir ? path40.join(dir, options.subdir) : dir;
29333
- const exe = path40.join(bin, exeName);
29728
+ const bin = options.subdir ? path43.join(dir, options.subdir) : dir;
29729
+ const exe = path43.join(bin, exeName);
29334
29730
  if (!exists(exe) || options.refresh) {
29335
29731
  const size = options.size ? ", ~" + options.size : "";
29336
29732
  await installFromGithub(repo, pattern, {
@@ -29355,8 +29751,8 @@ async function setupBun(env) {
29355
29751
  );
29356
29752
  Object.assign(env.vars, {
29357
29753
  BUN_INSTALL: tool("bun"),
29358
- BUN_INSTALL_CACHE_DIR: path40.join(localDir, "bun-cache"),
29359
- BUN_TMPDIR: path40.join(localDir, "bun-tmp")
29754
+ BUN_INSTALL_CACHE_DIR: path43.join(localDir, "bun-cache"),
29755
+ BUN_TMPDIR: path43.join(localDir, "bun-tmp")
29360
29756
  });
29361
29757
  }
29362
29758
  async function setupDeno(env) {
@@ -29390,12 +29786,12 @@ async function setupUv(env) {
29390
29786
  { size: "20 MB" }
29391
29787
  );
29392
29788
  Object.assign(env.vars, uvVars());
29393
- env.prepend.push(tool("uv-bin"));
29789
+ env.prepend.push(mkdirp(tool("uv-bin")));
29394
29790
  }
29395
29791
 
29396
29792
  // src/guest/toolchains/tools/cli.ts
29397
29793
  function ghConfigDir() {
29398
- return path41.join(stateDir, "gh");
29794
+ return path44.join(stateDir, "gh");
29399
29795
  }
29400
29796
  var toolVars = {
29401
29797
  gh: () => ({
@@ -29410,16 +29806,16 @@ var shimOpenssl = (env) => {
29410
29806
  return;
29411
29807
  }
29412
29808
  const shims = mkdirp(tool("shims"));
29413
- fs32.copyFileSync(ensureCompiled("openssl"), path41.join(shims, "openssl.exe"));
29414
- fs32.rmSync(path41.join(shims, "openssl.cmd"), { force: true });
29809
+ fs34.copyFileSync(ensureCompiled("openssl"), path44.join(shims, "openssl.exe"));
29810
+ fs34.rmSync(path44.join(shims, "openssl.cmd"), { force: true });
29415
29811
  env.prepend.push(shims);
29416
29812
  env.summary.push("openssl: Git for Windows' copy");
29417
29813
  };
29418
29814
  async function setupCli(env, settings, gitAccess, refresh = false) {
29419
- const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path41.join(projectWorkspace(), ".github")) });
29815
+ const decisions = decideCli(settings, { gitAccess, hasGithubDir: exists(path44.join(projectWorkspace(), ".github")) });
29420
29816
  if (settings.gh && !decisions.gh.on) {
29421
29817
  env.summary.push("gh: off (" + decisions.gh.reason + ")");
29422
- if (exists(path41.join(ghConfigDir(), "hosts.yml")))
29818
+ if (exists(path44.join(ghConfigDir(), "hosts.yml")))
29423
29819
  warn(
29424
29820
  'gh is off (git access is not "full"), but an earlier gh login is still stored in ' + ghConfigDir() + " and readable by the agent. Run `gh auth logout` in a full-access sandbox, or delete that folder."
29425
29821
  );
@@ -29456,12 +29852,12 @@ async function setupCli(env, settings, gitAccess, refresh = false) {
29456
29852
  }
29457
29853
 
29458
29854
  // src/guest/toolchains/managers.ts
29459
- import fs33 from "node:fs";
29460
- import path42 from "node:path";
29855
+ import fs35 from "node:fs";
29856
+ import path45 from "node:path";
29461
29857
  function voltaPins() {
29462
29858
  try {
29463
29859
  const pkg = JSON.parse(
29464
- fs33.readFileSync(path42.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
29860
+ fs35.readFileSync(path45.join(projectWorkspace(), "package.json"), "utf8").replace(/^\uFEFF/, "")
29465
29861
  );
29466
29862
  return Object.fromEntries(
29467
29863
  Object.entries(pkg.volta ?? {}).filter(
@@ -29484,7 +29880,7 @@ async function setupVolta(env) {
29484
29880
  return;
29485
29881
  }
29486
29882
  const dir = tool("volta");
29487
- if (!exists(path42.join(dir, "volta.exe"))) {
29883
+ if (!exists(path45.join(dir, "volta.exe"))) {
29488
29884
  const pattern = arch === "arm64" ? /^volta-[\d.]+-windows-arm64\.zip$/ : /^volta-[\d.]+-windows\.zip$/;
29489
29885
  await installFromGithub("volta-cli/volta", pattern, {
29490
29886
  dest: dir,
@@ -29493,17 +29889,17 @@ async function setupVolta(env) {
29493
29889
  });
29494
29890
  }
29495
29891
  for (const shim3 of ["node", "npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"]) {
29496
- const target = path42.join(dir, shim3 + ".exe");
29497
- if (!exists(target)) fs33.copyFileSync(path42.join(dir, "volta-shim.exe"), target);
29892
+ const target = path45.join(dir, shim3 + ".exe");
29893
+ if (!exists(target)) fs35.copyFileSync(path45.join(dir, "volta-shim.exe"), target);
29498
29894
  }
29499
29895
  const home = mkdirp(tool("volta-home"));
29500
- const shims = mkdirp(path42.join(home, "bin"));
29896
+ const shims = mkdirp(path45.join(home, "bin"));
29501
29897
  const vars = { VOLTA_HOME: home, VOLTA_FEATURE_PNPM: "1" };
29502
29898
  Object.assign(env.vars, vars);
29503
29899
  const pins = voltaPins();
29504
29900
  if (Object.keys(pins).length) env.prepend.push(dir, shims);
29505
29901
  else env.append.push(dir, shims);
29506
- const volta = path42.join(dir, "volta.exe");
29902
+ const volta = path45.join(dir, "volta.exe");
29507
29903
  for (const [toolName, version2] of Object.entries(pins)) {
29508
29904
  try {
29509
29905
  await execAsync(volta, ["install", toolName + "@" + version2], {
@@ -29525,7 +29921,7 @@ async function setupPyenv(env) {
29525
29921
  return;
29526
29922
  }
29527
29923
  const root = tool("pyenv", "pyenv-win");
29528
- if (!exists(path42.join(root, "bin", "pyenv.bat"))) {
29924
+ if (!exists(path45.join(root, "bin", "pyenv.bat"))) {
29529
29925
  const tag = await resolveCached("pyenv-win", () => latestGithubTag("pyenv-win/pyenv-win"));
29530
29926
  log("Downloading pyenv-win " + tag + " (~5 MB once) ...");
29531
29927
  await downloader.archive(
@@ -29534,17 +29930,17 @@ async function setupPyenv(env) {
29534
29930
  { locate: "pyenv.bat", up: 1, fileName: "pyenv-win.zip" }
29535
29931
  );
29536
29932
  }
29537
- const home = root + path42.sep;
29933
+ const home = root + path45.sep;
29538
29934
  Object.assign(env.vars, { PYENV: home, PYENV_ROOT: home, PYENV_HOME: home });
29539
- env.append.push(path42.join(root, "bin"), path42.join(root, "shims"));
29935
+ env.append.push(path45.join(root, "bin"), path45.join(root, "shims"));
29540
29936
  env.summary.push("pyenv-win: pyenv install <version> / pyenv local <version> (versions persist)");
29541
29937
  }
29542
29938
 
29543
29939
  // src/guest/toolchains/native/cpp.ts
29544
- import path43 from "node:path";
29940
+ import path46 from "node:path";
29545
29941
  async function setupCpp(env, config2) {
29546
29942
  const bin = tool("mingw", "mingw64", "bin");
29547
- const gcc = path43.join(bin, "gcc.exe");
29943
+ const gcc = path46.join(bin, "gcc.exe");
29548
29944
  if (dryRun) {
29549
29945
  log("(dry run) would provision MinGW-w64 GCC");
29550
29946
  return;
@@ -29560,7 +29956,7 @@ async function setupCpp(env, config2) {
29560
29956
  if (!exists(gcc)) throw new Error("gcc.exe missing after installing MinGW");
29561
29957
  env.append.unshift(bin);
29562
29958
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gcc;
29563
- const cmake = versionOf(path43.join(bin, "cmake.exe"));
29959
+ const cmake = versionOf(path46.join(bin, "cmake.exe"));
29564
29960
  if (cmakeTooOld(cmake))
29565
29961
  warn(
29566
29962
  "The bundled CMake " + cmake + " is older than " + CMAKE_FLOOR + ", which many projects need; set toolchains.cpp.enabled to refresh it, or install a newer CMake into C:\\AgentData\\tools\\bin."
@@ -29570,7 +29966,7 @@ async function setupCpp(env, config2) {
29570
29966
  }
29571
29967
  var setupFlexBison = async (env) => {
29572
29968
  const dir = tool("winflexbison");
29573
- if (!exists(path43.join(dir, "win_bison.exe"))) {
29969
+ if (!exists(path46.join(dir, "win_bison.exe"))) {
29574
29970
  await installFromGithub("lexxmark/winflexbison", /^win_flex_bison-[\d.]+\.zip$/, {
29575
29971
  dest: dir,
29576
29972
  what: "win_flex / win_bison (~1 MB once)",
@@ -29578,16 +29974,16 @@ var setupFlexBison = async (env) => {
29578
29974
  });
29579
29975
  }
29580
29976
  env.append.push(dir);
29581
- env.summary.push("win_flex/win_bison: " + versionOf(path43.join(dir, "win_bison.exe")));
29977
+ env.summary.push("win_flex/win_bison: " + versionOf(path46.join(dir, "win_bison.exe")));
29582
29978
  };
29583
29979
 
29584
29980
  // src/guest/toolchains/native/dotnet.ts
29585
- import fs34 from "node:fs";
29586
- import path44 from "node:path";
29981
+ import fs36 from "node:fs";
29982
+ import path47 from "node:path";
29587
29983
  var DotnetMarkerSchema = external_exports.record(external_exports.string(), external_exports.boolean());
29588
29984
  async function setupDotnet(env, config2, refresh) {
29589
29985
  const root = tool("dotnet");
29590
- const marker = path44.join(root, ".agent-sandbox-installed.json");
29986
+ const marker = path47.join(root, ".agent-sandbox-installed.json");
29591
29987
  const script = tool("dotnet-install.ps1");
29592
29988
  if (dryRun) {
29593
29989
  log("(dry run) would provision .NET SDK channels " + config2.channels.join(", "));
@@ -29595,11 +29991,11 @@ async function setupDotnet(env, config2, refresh) {
29595
29991
  }
29596
29992
  const recorded = DotnetMarkerSchema.safeParse(exists(marker) && !refresh ? readJsonFile(marker) : {});
29597
29993
  const done = recorded.success ? recorded.data : {};
29598
- const globalJson = path44.join(projectWorkspace(), "global.json");
29994
+ const globalJson = path47.join(projectWorkspace(), "global.json");
29599
29995
  const installs = [
29600
29996
  ...config2.channels.map((c) => ["channel:" + c, ["-Channel", c]]),
29601
29997
  ...exists(globalJson) ? [
29602
- ["global.json:" + fs34.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
29998
+ ["global.json:" + fs36.readFileSync(globalJson, "utf8").replace(/\s+/g, ""), ["-JSonFile", globalJson]]
29603
29999
  ] : []
29604
30000
  ];
29605
30001
  for (const [key, args] of installs.filter(([k]) => !done[k])) {
@@ -29631,12 +30027,12 @@ async function setupDotnet(env, config2, refresh) {
29631
30027
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1",
29632
30028
  NUGET_PACKAGES: tool("nuget", "packages")
29633
30029
  });
29634
- env.prepend.push(root, path44.join(home, ".dotnet", "tools"));
30030
+ env.prepend.push(root, path47.join(home, ".dotnet", "tools"));
29635
30031
  env.summary.push(
29636
- "dotnet: " + execOutput(path44.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", ")
30032
+ "dotnet: " + execOutput(path47.join(root, "dotnet.exe"), ["--list-sdks"]).split(/\r?\n/).map((l) => l.split(" ")[0]).filter(Boolean).join(", ")
29637
30033
  );
29638
- const dotnet = path44.join(root, "dotnet.exe");
29639
- const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path44.delimiter + (process.env.PATH ?? "") } };
30034
+ const dotnet = path47.join(root, "dotnet.exe");
30035
+ const dotnetEnv = { env: { ...process.env, ...env.vars, PATH: root + path47.delimiter + (process.env.PATH ?? "") } };
29640
30036
  await installOnce(
29641
30037
  env,
29642
30038
  "dotnet workload",
@@ -29657,7 +30053,7 @@ var setupFrameworkReferences = async (env, targets) => {
29657
30053
  const root = tool("netfx-references");
29658
30054
  for (const target of targets) {
29659
30055
  const id = "microsoft.netframework.referenceassemblies." + target.toLowerCase();
29660
- const marker = path44.join(root, ".installed-" + target.toLowerCase());
30056
+ const marker = path47.join(root, ".installed-" + target.toLowerCase());
29661
30057
  if (exists(marker)) continue;
29662
30058
  const staging = tool("netfx-references-" + target.toLowerCase());
29663
30059
  try {
@@ -29672,8 +30068,8 @@ var setupFrameworkReferences = async (env, targets) => {
29672
30068
  staging,
29673
30069
  { fileName: id + ".zip" }
29674
30070
  );
29675
- fs34.cpSync(path44.join(staging, "build", ".NETFramework"), path44.join(root, ".NETFramework"), { recursive: true });
29676
- fs34.writeFileSync(marker, version2);
30071
+ fs36.cpSync(path47.join(staging, "build", ".NETFramework"), path47.join(root, ".NETFramework"), { recursive: true });
30072
+ fs36.writeFileSync(marker, version2);
29677
30073
  } catch (e) {
29678
30074
  warn(
29679
30075
  ".NET Framework " + target + " reference assemblies could not be installed (projects targeting it will not build): " + errMsg(e)
@@ -29682,9 +30078,9 @@ var setupFrameworkReferences = async (env, targets) => {
29682
30078
  safeRemove(staging, dataDir);
29683
30079
  }
29684
30080
  }
29685
- if (!exists(path44.join(root, ".NETFramework"))) return;
29686
- env.vars.TargetFrameworkRootPath = root + path44.sep;
29687
- env.summary.push(".NET Framework targeting: " + fs34.readdirSync(path44.join(root, ".NETFramework")).join(", "));
30081
+ if (!exists(path47.join(root, ".NETFramework"))) return;
30082
+ env.vars.TargetFrameworkRootPath = root + path47.sep;
30083
+ env.summary.push(".NET Framework targeting: " + fs36.readdirSync(path47.join(root, ".NETFramework")).join(", "));
29688
30084
  };
29689
30085
  var setupNetFx35 = async (env) => {
29690
30086
  if (execOutput(SYSTEM.reg(), [
@@ -29711,15 +30107,15 @@ var setupNetFx35 = async (env) => {
29711
30107
  };
29712
30108
 
29713
30109
  // src/guest/toolchains/native/mesa.ts
29714
- import path45 from "node:path";
30110
+ import path48 from "node:path";
29715
30111
  async function setupMesa(env, config2) {
29716
30112
  if (dryRun) {
29717
30113
  log("(dry run) would provision Mesa 3D");
29718
30114
  return;
29719
30115
  }
29720
30116
  const root = tool("mesa");
29721
- const dir = path45.join(root, arch === "arm64" ? "arm64" : "x64");
29722
- if (!exists(path45.join(dir, "opengl32.dll"))) {
30117
+ const dir = path48.join(root, arch === "arm64" ? "arm64" : "x64");
30118
+ if (!exists(path48.join(dir, "opengl32.dll"))) {
29723
30119
  await installFromGithub("pal1000/mesa-dist-win", /^mesa3d-[\d.]+-release-msvc\.7z$/, {
29724
30120
  dest: root,
29725
30121
  what: "Mesa 3D for software OpenGL (~100 MB once)",
@@ -29735,10 +30131,10 @@ async function setupMesa(env, config2) {
29735
30131
  }
29736
30132
  var VULKAN_RUNTIME = "https://sdk.lunarg.com/sdk/download/latest/windows/vulkan-runtime-components.zip";
29737
30133
  var setupLavapipe = async (env, mesaDir) => {
29738
- const icd = path45.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
29739
- if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path45.basename(icd) + ")");
30134
+ const icd = path48.join(mesaDir, arch === "arm64" ? "lvp_icd.aarch64.json" : "lvp_icd.x86_64.json");
30135
+ if (!exists(icd)) throw new Error("this Mesa build has no lavapipe (" + path48.basename(icd) + ")");
29740
30136
  const dir = tool("vulkan");
29741
- if (!exists(path45.join(dir, "vulkan-1.dll"))) {
30137
+ if (!exists(path48.join(dir, "vulkan-1.dll"))) {
29742
30138
  log("Downloading the Vulkan loader (~10 MB once) ...");
29743
30139
  await downloader.archive(VULKAN_RUNTIME, dir, {
29744
30140
  locate: "vulkan-1.dll",
@@ -29752,7 +30148,7 @@ var setupLavapipe = async (env, mesaDir) => {
29752
30148
  { stdio: "ignore" }
29753
30149
  );
29754
30150
  await register(icd);
29755
- const dozen = path45.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
30151
+ const dozen = path48.join(mesaDir, arch === "arm64" ? "dzn_icd.aarch64.json" : "dzn_icd.x86_64.json");
29756
30152
  const gpu = hasGpu();
29757
30153
  if (gpu && exists(dozen)) await register(dozen);
29758
30154
  env.prepend.push(dir);
@@ -29763,20 +30159,20 @@ var setupLavapipe = async (env, mesaDir) => {
29763
30159
  var hasGpu = () => scriptOutput("get-gpu-names.ps1", [], { timeout: 3e4 }).split(/\r?\n/).map((n) => n.trim()).some((n) => n && !/^Microsoft (Remote Display|Basic (Render|Display))/i.test(n));
29764
30160
 
29765
30161
  // src/guest/toolchains/native/msvc/index.ts
29766
- import fs38 from "node:fs";
29767
- import path49 from "node:path";
30162
+ import fs40 from "node:fs";
30163
+ import path52 from "node:path";
29768
30164
 
29769
30165
  // src/guest/toolchains/native/msvc/environment.ts
29770
- import fs36 from "node:fs";
29771
- import path47 from "node:path";
30166
+ import fs38 from "node:fs";
30167
+ import path50 from "node:path";
29772
30168
 
29773
30169
  // src/guest/toolchains/native/msvc/tree.ts
29774
- import fs35 from "node:fs";
29775
- import path46 from "node:path";
30170
+ import fs37 from "node:fs";
30171
+ import path49 from "node:path";
29776
30172
  var ROOT = tool("msvc");
29777
- var MARKER2 = path46.join(ROOT, ".installed.json");
30173
+ var MARKER2 = path49.join(ROOT, ".installed.json");
29778
30174
  function msvcTools(msvc, ...parts2) {
29779
- return path46.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts2);
30175
+ return path49.join(ROOT, "VC", "Tools", "MSVC", msvc, ...parts2);
29780
30176
  }
29781
30177
  function hostBin(msvc, ...parts2) {
29782
30178
  return msvcTools(msvc, "bin", "Hostx64", "x64", ...parts2);
@@ -29787,27 +30183,27 @@ function hasCompiler(msvc) {
29787
30183
  var InstalledSchema = external_exports.object({ msvc: external_exports.string().min(1), sdk: external_exports.string().min(1), want: external_exports.string() });
29788
30184
  function readInstalled() {
29789
30185
  try {
29790
- return InstalledSchema.safeParse(JSON.parse(fs35.readFileSync(MARKER2, "utf8"))).data ?? null;
30186
+ return InstalledSchema.safeParse(JSON.parse(fs37.readFileSync(MARKER2, "utf8"))).data ?? null;
29791
30187
  } catch {
29792
30188
  return null;
29793
30189
  }
29794
30190
  }
29795
30191
 
29796
30192
  // src/guest/toolchains/native/msvc/environment.ts
29797
- var VSWHERE_DIR = path47.join(
30193
+ var VSWHERE_DIR = path50.join(
29798
30194
  process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)",
29799
30195
  "Microsoft Visual Studio",
29800
30196
  "Installer"
29801
30197
  );
29802
30198
  function vcvars(root, msvc, sdk) {
29803
- const vc = path47.join(root, "VC", "Tools", "MSVC", msvc);
29804
- const kits = path47.join(root, "Windows Kits", "10");
29805
- const inc = (...p) => path47.join(kits, "Include", sdk, ...p);
29806
- const lib = (...p) => path47.join(kits, "Lib", sdk, ...p);
30199
+ const vc = path50.join(root, "VC", "Tools", "MSVC", msvc);
30200
+ const kits = path50.join(root, "Windows Kits", "10");
30201
+ const inc = (...p) => path50.join(kits, "Include", sdk, ...p);
30202
+ const lib = (...p) => path50.join(kits, "Lib", sdk, ...p);
29807
30203
  return {
29808
30204
  vars: {
29809
30205
  VSINSTALLDIR: root + "\\",
29810
- VCINSTALLDIR: path47.join(root, "VC") + "\\",
30206
+ VCINSTALLDIR: path50.join(root, "VC") + "\\",
29811
30207
  VCToolsInstallDir: vc + "\\",
29812
30208
  VCToolsVersion: msvc,
29813
30209
  VisualStudioVersion: "17.0",
@@ -29819,17 +30215,17 @@ function vcvars(root, msvc, sdk) {
29819
30215
  VSCMD_ARG_HOST_ARCH: "x64",
29820
30216
  VSCMD_ARG_TGT_ARCH: "x64",
29821
30217
  Platform: "x64",
29822
- INCLUDE: [path47.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(
30218
+ INCLUDE: [path50.join(vc, "include"), inc("ucrt"), inc("shared"), inc("um"), inc("winrt"), inc("cppwinrt")].join(
29823
30219
  ";"
29824
30220
  ),
29825
- LIB: [path47.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
29826
- LIBPATH: [path47.join(vc, "lib", "x64"), path47.join(vc, "lib", "x86", "store", "references")].join(";")
30221
+ LIB: [path50.join(vc, "lib", "x64"), lib("ucrt", "x64"), lib("um", "x64")].join(";"),
30222
+ LIBPATH: [path50.join(vc, "lib", "x64"), path50.join(vc, "lib", "x86", "store", "references")].join(";")
29827
30223
  },
29828
- path: [path47.join(vc, "bin", "Hostx64", "x64"), path47.join(kits, "bin", sdk, "x64")]
30224
+ path: [path50.join(vc, "bin", "Hostx64", "x64"), path50.join(kits, "bin", sdk, "x64")]
29829
30225
  };
29830
30226
  }
29831
30227
  function writeVcvars(env) {
29832
- const dir = mkdirp(path47.join(ROOT, "VC", "Auxiliary", "Build"));
30228
+ const dir = mkdirp(path50.join(ROOT, "VC", "Auxiliary", "Build"));
29833
30229
  const lines = [
29834
30230
  "@echo off",
29835
30231
  "rem Written by Windows Development Sandbox for its portable MSVC (host x64, target x64).",
@@ -29837,9 +30233,9 @@ function writeVcvars(env) {
29837
30233
  'set "PATH=' + env.path.join(";") + ';%PATH%"',
29838
30234
  "exit /b 0"
29839
30235
  ];
29840
- fs36.writeFileSync(path47.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
29841
- fs36.writeFileSync(
29842
- path47.join(dir, "vcvarsall.bat"),
30236
+ fs38.writeFileSync(path50.join(dir, "vcvars64.bat"), lines.join("\r\n") + "\r\n");
30237
+ fs38.writeFileSync(
30238
+ path50.join(dir, "vcvarsall.bat"),
29843
30239
  ["@echo off", "rem Only x64 (amd64) is installed.", 'call "%~dp0vcvars64.bat"', "exit /b %errorlevel%"].join(
29844
30240
  "\r\n"
29845
30241
  ) + "\r\n"
@@ -29847,24 +30243,24 @@ function writeVcvars(env) {
29847
30243
  }
29848
30244
  function installVswhere(msvc) {
29849
30245
  mkdirp(VSWHERE_DIR);
29850
- fs36.copyFileSync(ensureCompiled("vswhere"), path47.join(VSWHERE_DIR, "vswhere.exe"));
30246
+ fs38.copyFileSync(ensureCompiled("vswhere"), path50.join(VSWHERE_DIR, "vswhere.exe"));
29851
30247
  const [major, minor] = msvc.split(".").slice(2);
29852
- fs36.writeFileSync(
29853
- path47.join(VSWHERE_DIR, "vswhere.json"),
30248
+ fs38.writeFileSync(
30249
+ path50.join(VSWHERE_DIR, "vswhere.json"),
29854
30250
  JSON.stringify({ installationPath: ROOT, installationVersion: "17." + (minor ?? "0") + ".0." + (major ?? "0") })
29855
30251
  );
29856
30252
  }
29857
30253
  function removeTelemetry(msvc) {
29858
30254
  try {
29859
- fs36.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
30255
+ fs38.rmSync(hostBin(msvc, "vctip.exe"), { force: true });
29860
30256
  } catch (e) {
29861
30257
  warn("Could not remove MSVC's telemetry helper (vctip.exe); it may keep tools\\msvc locked: " + errMsg(e));
29862
30258
  }
29863
30259
  }
29864
30260
 
29865
30261
  // src/guest/toolchains/native/msvc/packages.ts
29866
- import fs37 from "node:fs";
29867
- import path48 from "node:path";
30262
+ import fs39 from "node:fs";
30263
+ import path51 from "node:path";
29868
30264
  var CHANNEL = "https://aka.ms/vs/17/release/channel";
29869
30265
  var MANIFEST_DAY_MS = 24 * 60 * 60 * 1e3;
29870
30266
  var MSVC_PARTS = [
@@ -29890,10 +30286,10 @@ var SDK_MSIS = [
29890
30286
  "Windows SDK Desktop Tools x64-x86_en-us.msi"
29891
30287
  ];
29892
30288
  var manifest = async () => {
29893
- const cached2 = path48.join(ROOT, ".manifest.json");
29894
- if (exists(cached2) && Date.now() - fs37.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
30289
+ const cached2 = path51.join(ROOT, ".manifest.json");
30290
+ if (exists(cached2) && Date.now() - fs39.statSync(cached2).mtimeMs < MANIFEST_DAY_MS) {
29895
30291
  try {
29896
- return JSON.parse(fs37.readFileSync(cached2, "utf8"));
30292
+ return JSON.parse(fs39.readFileSync(cached2, "utf8"));
29897
30293
  } catch {
29898
30294
  }
29899
30295
  }
@@ -29902,26 +30298,26 @@ var manifest = async () => {
29902
30298
  if (!item) throw new Error("the Visual Studio channel has no package manifest");
29903
30299
  mkdirp(ROOT);
29904
30300
  await downloader.file(item.url, cached2);
29905
- return JSON.parse(fs37.readFileSync(cached2, "utf8"));
30301
+ return JSON.parse(fs39.readFileSync(cached2, "utf8"));
29906
30302
  };
29907
30303
  var unpackVsix = async (vsix, work) => {
29908
- const out = mkdirp(path48.join(work, "vsix-" + path48.basename(vsix)));
30304
+ const out = mkdirp(path51.join(work, "vsix-" + path51.basename(vsix)));
29909
30305
  await extractArchive(vsix, out, ["Contents"]);
29910
30306
  const decode4 = (dir) => {
29911
- for (const entry of fs37.readdirSync(dir, { withFileTypes: true })) {
29912
- const from = path48.join(dir, entry.name);
30307
+ for (const entry of fs39.readdirSync(dir, { withFileTypes: true })) {
30308
+ const from = path51.join(dir, entry.name);
29913
30309
  let name = entry.name;
29914
30310
  try {
29915
30311
  if (name.includes("%")) name = decodeURIComponent(name);
29916
30312
  } catch {
29917
30313
  }
29918
- const to = path48.join(dir, name);
29919
- if (to !== from) fs37.renameSync(from, to);
30314
+ const to = path51.join(dir, name);
30315
+ if (to !== from) fs39.renameSync(from, to);
29920
30316
  if (entry.isDirectory()) decode4(to);
29921
30317
  }
29922
30318
  };
29923
30319
  decode4(out);
29924
- fs37.cpSync(path48.join(out, "Contents"), ROOT, { recursive: true, force: true });
30320
+ fs39.cpSync(path51.join(out, "Contents"), ROOT, { recursive: true, force: true });
29925
30321
  safeRemove(out, work);
29926
30322
  };
29927
30323
  var unpackMsi = async (msi) => {
@@ -29931,9 +30327,9 @@ var unpackMsi = async (msi) => {
29931
30327
  stdio: "ignore"
29932
30328
  });
29933
30329
  } catch (e) {
29934
- const lines = exists(logFile2) ? fs37.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
30330
+ const lines = exists(logFile2) ? fs39.readFileSync(logFile2, "utf16le").split(/\r?\n/).filter((l) => /error|return value 3|failed/i.test(l)).slice(-4).join(" | ") : "";
29935
30331
  throw new Error(
29936
- path48.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
30332
+ path51.basename(msi) + " did not unpack: " + (e instanceof Error ? e.message : String(e)) + (lines ? " (" + lines.slice(0, 600) + ")" : "")
29937
30333
  );
29938
30334
  }
29939
30335
  };
@@ -29946,13 +30342,13 @@ var catalogue = (m) => {
29946
30342
  };
29947
30343
  };
29948
30344
  var payloadFetcher = (work) => async (p) => {
29949
- const file3 = path48.join(work, path48.basename(p.fileName.replace(/\\/g, "/")));
30345
+ const file3 = path51.join(work, path51.basename(p.fileName.replace(/\\/g, "/")));
29950
30346
  if (!exists(file3)) await downloader.file(p.url, file3, p.sha256);
29951
30347
  return file3;
29952
30348
  };
29953
30349
  var unpackedToolset = () => {
29954
- const toolsRoot = path48.join(ROOT, "VC", "Tools", "MSVC");
29955
- return fs37.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
30350
+ const toolsRoot = path51.join(ROOT, "VC", "Tools", "MSVC");
30351
+ return fs39.readdirSync(toolsRoot).filter((d) => exists(hostBin(d, "cl.exe"))).sort((a, b) => a.localeCompare(b, void 0, { numeric: true })).pop();
29956
30352
  };
29957
30353
  async function installPackages(config2) {
29958
30354
  const { ids, pick: pick2 } = catalogue(await manifest());
@@ -29960,7 +30356,7 @@ async function installPackages(config2) {
29960
30356
  if (!version2) throw new Error("no MSVC " + config2.msvcVersion + " in the Visual Studio manifest");
29961
30357
  const sdk = pickWindowsSdk(ids, config2.sdkVersion);
29962
30358
  if (!sdk) throw new Error("no Windows SDK " + config2.sdkVersion + " in the Visual Studio manifest");
29963
- const work = mkdirp(path48.join(ROOT, ".download"));
30359
+ const work = mkdirp(path51.join(ROOT, ".download"));
29964
30360
  const fetchPayload = payloadFetcher(work);
29965
30361
  log("Downloading the MSVC " + version2 + " compiler and C/C++ libraries ...");
29966
30362
  for (const part of MSVC_PARTS) {
@@ -29980,17 +30376,17 @@ async function installPackages(config2) {
29980
30376
  if (!p) throw new Error("the Windows SDK package has no " + name);
29981
30377
  const file3 = await fetchPayload(p);
29982
30378
  msis.push(file3);
29983
- for (const cab of msiCabs(fs37.readFileSync(file3))) {
30379
+ for (const cab of msiCabs(fs39.readFileSync(file3))) {
29984
30380
  const c = payload(cab);
29985
30381
  if (c) await fetchPayload(c);
29986
30382
  }
29987
30383
  }
29988
30384
  log("Unpacking the Windows SDK (a few minutes) ...");
29989
30385
  for (const msi of msis) await unpackMsi(msi);
29990
- for (const name of fs37.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
29991
- fs37.rmSync(path48.join(ROOT, name), { force: true });
30386
+ for (const name of fs39.readdirSync(ROOT).filter((n) => n.toLowerCase().endsWith(".msi")))
30387
+ fs39.rmSync(path51.join(ROOT, name), { force: true });
29992
30388
  safeRemove(work, ROOT);
29993
- const sdkVersion = fs37.readdirSync(path48.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
30389
+ const sdkVersion = fs39.readdirSync(path51.join(ROOT, "Windows Kits", "10", "Include")).filter((d) => d.startsWith("10.0." + sdk.build)).sort().pop();
29994
30390
  if (!sdkVersion) throw new Error("the Windows SDK did not unpack (no Include\\10.0." + sdk.build + ".*)");
29995
30391
  const toolset = unpackedToolset();
29996
30392
  if (!toolset) throw new Error("MSVC " + version2 + " did not unpack (no cl.exe under VC\\Tools\\MSVC)");
@@ -30004,8 +30400,8 @@ function installedMsvcEnv() {
30004
30400
  }
30005
30401
  var clearTree = () => {
30006
30402
  if (!exists(ROOT)) return;
30007
- for (const name of fs38.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
30008
- safeRemove(path49.join(ROOT, name), ROOT);
30403
+ for (const name of fs40.readdirSync(ROOT).filter((n) => n !== ".manifest.json" && n !== ".download"))
30404
+ safeRemove(path52.join(ROOT, name), ROOT);
30009
30405
  };
30010
30406
  async function setupMsvc(env, config2) {
30011
30407
  if (!config2.acceptLicense) {
@@ -30035,24 +30431,24 @@ async function setupMsvc(env, config2) {
30035
30431
  }
30036
30432
 
30037
30433
  // src/guest/toolchains/native/rust.ts
30038
- import path51 from "node:path";
30434
+ import path54 from "node:path";
30039
30435
 
30040
30436
  // src/guest/toolchains/native/binstall.ts
30041
- import fs39 from "node:fs";
30042
- import path50 from "node:path";
30437
+ import fs41 from "node:fs";
30438
+ import path53 from "node:path";
30043
30439
  var ensureBinstall = async (cargoBin) => {
30044
- const target = path50.join(cargoBin, "cargo-binstall.exe");
30440
+ const target = path53.join(cargoBin, "cargo-binstall.exe");
30045
30441
  if (exists(target)) return true;
30046
30442
  try {
30047
30443
  const dir = tool("cargo-binstall");
30048
- if (!exists(path50.join(dir, "cargo-binstall.exe"))) {
30444
+ if (!exists(path53.join(dir, "cargo-binstall.exe"))) {
30049
30445
  await installFromGithub("cargo-bins/cargo-binstall", binstallAsset(arch), {
30050
30446
  dest: dir,
30051
30447
  what: "cargo-binstall for prebuilt Rust tools (~10 MB once)",
30052
30448
  locate: "cargo-binstall.exe"
30053
30449
  });
30054
30450
  }
30055
- fs39.copyFileSync(path50.join(dir, "cargo-binstall.exe"), target);
30451
+ fs41.copyFileSync(path53.join(dir, "cargo-binstall.exe"), target);
30056
30452
  return true;
30057
30453
  } catch (e) {
30058
30454
  warn("cargo-binstall unavailable, compiling crates with cargo install instead: " + errMsg(e));
@@ -30060,14 +30456,14 @@ var ensureBinstall = async (cargoBin) => {
30060
30456
  }
30061
30457
  };
30062
30458
  function crateInstaller(cargoHome, cargoEnv) {
30063
- const cargo = path50.join(cargoHome, "bin", "cargo.exe");
30459
+ const cargo = path53.join(cargoHome, "bin", "cargo.exe");
30064
30460
  let binstall = null;
30065
30461
  const binstallEnv = {
30066
30462
  ...cargoEnv,
30067
30463
  env: { ...cargoEnv.env ?? process.env, BINSTALL_DISABLE_TELEMETRY: "true" }
30068
30464
  };
30069
30465
  return async (crate) => {
30070
- binstall ??= ensureBinstall(path50.join(cargoHome, "bin"));
30466
+ binstall ??= ensureBinstall(path53.join(cargoHome, "bin"));
30071
30467
  if (await binstall) {
30072
30468
  try {
30073
30469
  await execAsync(
@@ -30089,7 +30485,7 @@ async function setupRust(env, config2, refresh) {
30089
30485
  const RUSTUP_HOME = tool("rust", "rustup");
30090
30486
  const CARGO_HOME = tool("rust", "cargo");
30091
30487
  const rustEnv = { env: { ...process.env, RUSTUP_HOME, CARGO_HOME } };
30092
- const rustup = path51.join(CARGO_HOME, "bin", "rustup.exe");
30488
+ const rustup = path54.join(CARGO_HOME, "bin", "rustup.exe");
30093
30489
  if (dryRun) {
30094
30490
  log("(dry run) would provision Rust " + config2.toolchain + " (" + config2.host + ")");
30095
30491
  return;
@@ -30125,9 +30521,9 @@ async function setupRust(env, config2, refresh) {
30125
30521
  if (refresh) await execAsync(rustup, ["update"], rustEnv);
30126
30522
  }
30127
30523
  Object.assign(env.vars, { RUSTUP_HOME, CARGO_HOME });
30128
- env.prepend.push(path51.join(CARGO_HOME, "bin"));
30524
+ env.prepend.push(path54.join(CARGO_HOME, "bin"));
30129
30525
  env.summary.push(
30130
- "rust: " + versionOf(path51.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30526
+ "rust: " + versionOf(path54.join(CARGO_HOME, "bin", "rustc.exe"), ["--version"], rustEnv) + " [" + config2.host + "]"
30131
30527
  );
30132
30528
  const toolchainKey = "rustup@" + config2.toolchain;
30133
30529
  await installOnce(
@@ -30148,36 +30544,36 @@ async function setupRust(env, config2, refresh) {
30148
30544
  env: {
30149
30545
  ...rustEnv.env,
30150
30546
  ...msvc.vars,
30151
- PATH: [path51.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path51.delimiter)
30547
+ PATH: [path54.join(CARGO_HOME, "bin"), ...msvc.path, process.env.PATH ?? ""].join(path54.delimiter)
30152
30548
  }
30153
30549
  } : {
30154
30550
  env: {
30155
30551
  ...rustEnv.env,
30156
- CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path51.join(mingw, "gcc.exe"),
30157
- PATH: [path51.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path51.delimiter)
30552
+ CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: path54.join(mingw, "gcc.exe"),
30553
+ PATH: [path54.join(CARGO_HOME, "bin"), mingw, process.env.PATH ?? ""].join(path54.delimiter)
30158
30554
  }
30159
30555
  };
30160
30556
  await installOnce(env, "cargo", config2.crates, crateInstaller(CARGO_HOME, cargoEnv));
30161
30557
  }
30162
30558
 
30163
30559
  // src/guest/toolchains/languages/node.ts
30164
- import fs40 from "node:fs";
30165
- import path52 from "node:path";
30560
+ import fs42 from "node:fs";
30561
+ import path55 from "node:path";
30166
30562
  import { spawn as spawn4 } from "node:child_process";
30167
30563
  var NVM_HOME = tool("nvm");
30168
- var NVM_SYMLINK = path52.join(localDir, "nodejs");
30169
- var HOST_NVM = path52.join(hostToolsDir, "nvm");
30564
+ var NVM_SYMLINK = path55.join(localDir, "nodejs");
30565
+ var HOST_NVM = path55.join(hostToolsDir, "nvm");
30170
30566
  var HOST_VERSIONS_MAX = 3;
30171
- var hostNvmVersions = () => exists(HOST_NVM) ? fs40.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path52.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
30567
+ var hostNvmVersions = () => exists(HOST_NVM) ? fs42.readdirSync(HOST_NVM).filter((d) => /^v\d+\.\d+\.\d+$/.test(d) && exists(path55.join(HOST_NVM, d, "node.exe"))).map((d) => d.slice(1)) : [];
30172
30568
  var resolveNode = (spec) => resolveCached("node:" + spec, async () => {
30173
30569
  const exact = spec.replace(/^v/, "");
30174
30570
  if (/^\d+\.\d+\.\d+$/.test(exact)) return exact;
30175
30571
  const releases = await fetchJson("https://nodejs.org/dist/index.json");
30176
30572
  return pickNodeVersion(releases, spec) ?? Promise.reject(new Error('No Node.js release matches "' + spec + '"'));
30177
30573
  });
30178
- var NVM_TEMP = path52.join(NVM_HOME, ".tmp");
30574
+ var NVM_TEMP = path55.join(NVM_HOME, ".tmp");
30179
30575
  var nvm = (args) => new Promise((resolve2) => {
30180
- const child = spawn4(path52.join(NVM_HOME, "nvm.exe"), args, {
30576
+ const child = spawn4(path55.join(NVM_HOME, "nvm.exe"), args, {
30181
30577
  windowsHide: true,
30182
30578
  env: { ...process.env, NVM_HOME, NVM_SYMLINK, TEMP: NVM_TEMP, TMP: NVM_TEMP }
30183
30579
  });
@@ -30192,12 +30588,12 @@ var nvm = (args) => new Promise((resolve2) => {
30192
30588
  child.once("close", () => resolve2(out));
30193
30589
  });
30194
30590
  var ensureNvm = async () => {
30195
- if (exists(path52.join(NVM_HOME, "nvm.exe"))) return;
30196
- if (exists(path52.join(HOST_NVM, "nvm.exe"))) {
30591
+ if (exists(path55.join(NVM_HOME, "nvm.exe"))) return;
30592
+ if (exists(path55.join(HOST_NVM, "nvm.exe"))) {
30197
30593
  log("Copying nvm from this PC ...");
30198
30594
  mkdirp(NVM_HOME);
30199
- const files = fs40.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
30200
- for (const file3 of files) fs40.copyFileSync(path52.join(HOST_NVM, file3), path52.join(NVM_HOME, file3));
30595
+ const files = fs42.readdirSync(HOST_NVM).filter((f) => /\.(exe|cmd|vbs)$/i.test(f)).sort((a, b) => Number(a.toLowerCase() === "nvm.exe") - Number(b.toLowerCase() === "nvm.exe"));
30596
+ for (const file3 of files) fs42.copyFileSync(path55.join(HOST_NVM, file3), path55.join(NVM_HOME, file3));
30201
30597
  return;
30202
30598
  }
30203
30599
  const asset = await githubAsset("coreybutler/nvm-windows", /^nvm-noinstall\.zip$/, true);
@@ -30205,10 +30601,10 @@ var ensureNvm = async () => {
30205
30601
  await downloader.archive(asset.url, NVM_HOME, { sha256: asset.sha256, locate: "nvm.exe", fileName: asset.name });
30206
30602
  };
30207
30603
  var installNodeVersion = async (version2) => {
30208
- const dir = path52.join(NVM_HOME, "v" + version2);
30209
- const fromHost = path52.join(HOST_NVM, "v" + version2);
30210
- if (exists(path52.join(dir, "node.exe"))) return;
30211
- if (exists(path52.join(fromHost, "node.exe"))) {
30604
+ const dir = path55.join(NVM_HOME, "v" + version2);
30605
+ const fromHost = path55.join(HOST_NVM, "v" + version2);
30606
+ if (exists(path55.join(dir, "node.exe"))) return;
30607
+ if (exists(path55.join(fromHost, "node.exe"))) {
30212
30608
  log("Copying Node " + version2 + " from this PC's nvm (without global packages) ...");
30213
30609
  copyNode(fromHost, dir);
30214
30610
  return;
@@ -30221,14 +30617,14 @@ var installNodeVersion = async (version2) => {
30221
30617
  } finally {
30222
30618
  safeRemove(NVM_TEMP, NVM_HOME);
30223
30619
  }
30224
- if (!exists(path52.join(dir, "node.exe")))
30620
+ if (!exists(path55.join(dir, "node.exe")))
30225
30621
  throw new Error("nvm install " + version2 + " failed: " + out.trim().split("\n").slice(-2).join(" "));
30226
30622
  };
30227
30623
  var activate = async (version2) => {
30228
30624
  await nvm(["use", version2]);
30229
- if (exists(path52.join(NVM_SYMLINK, "node.exe"))) return;
30230
- fs40.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30231
- fs40.symlinkSync(path52.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30625
+ if (exists(path55.join(NVM_SYMLINK, "node.exe"))) return;
30626
+ fs42.rmSync(NVM_SYMLINK, { recursive: true, force: true });
30627
+ fs42.symlinkSync(path55.join(NVM_HOME, "v" + version2), NVM_SYMLINK, "junction");
30232
30628
  };
30233
30629
  async function setupNode(env, versions, config2) {
30234
30630
  if (dryRun) {
@@ -30236,8 +30632,8 @@ async function setupNode(env, versions, config2) {
30236
30632
  return;
30237
30633
  }
30238
30634
  await ensureNvm();
30239
- fs40.writeFileSync(
30240
- path52.join(NVM_HOME, "settings.txt"),
30635
+ fs42.writeFileSync(
30636
+ path55.join(NVM_HOME, "settings.txt"),
30241
30637
  [
30242
30638
  "root: " + NVM_HOME,
30243
30639
  "path: " + NVM_SYMLINK,
@@ -30264,7 +30660,7 @@ async function setupNode(env, versions, config2) {
30264
30660
  }
30265
30661
  }
30266
30662
  Object.assign(env.vars, { NVM_HOME, NVM_SYMLINK });
30267
- if (duringSession()) env.prepend.push(path52.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30663
+ if (duringSession()) env.prepend.push(path55.join(NVM_HOME, "v" + main), NVM_HOME, NVM_SYMLINK);
30268
30664
  else {
30269
30665
  await activate(main);
30270
30666
  env.prepend.push(NVM_HOME, NVM_SYMLINK);
@@ -30273,13 +30669,13 @@ async function setupNode(env, versions, config2) {
30273
30669
  await packageManagers(env, config2, main);
30274
30670
  }
30275
30671
  var packageManagers = async (env, config2, version2) => {
30276
- const dir = path52.join(NVM_HOME, "v" + version2);
30277
- const nodeEnv = { ...process.env, PATH: dir + path52.delimiter + (process.env.PATH ?? "") };
30278
- const npm = (args) => execAsync(path52.join(dir, "node.exe"), [path52.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30672
+ const dir = path55.join(NVM_HOME, "v" + version2);
30673
+ const nodeEnv = { ...process.env, PATH: dir + path55.delimiter + (process.env.PATH ?? "") };
30674
+ const npm = (args) => execAsync(path55.join(dir, "node.exe"), [path55.join(dir, "node_modules", "npm", "bin", "npm-cli.js"), ...args], {
30279
30675
  env: nodeEnv,
30280
30676
  stdio: "ignore"
30281
30677
  });
30282
- const corepackJs = path52.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30678
+ const corepackJs = path55.join(dir, "node_modules", "corepack", "dist", "corepack.js");
30283
30679
  const extra = config2.corepack && !exists(corepackJs) ? ["corepack"] : [];
30284
30680
  await installOnce(
30285
30681
  env,
@@ -30300,7 +30696,7 @@ var packageManagers = async (env, config2, version2) => {
30300
30696
  }
30301
30697
  try {
30302
30698
  await execAsync(
30303
- path52.join(dir, "node.exe"),
30699
+ path55.join(dir, "node.exe"),
30304
30700
  [corepackJs, "enable", "--install-directory", mkdirp(tool("bin")), "pnpm", "yarn"],
30305
30701
  { env: nodeEnv, stdio: "ignore" }
30306
30702
  );
@@ -30325,8 +30721,8 @@ async function setupPwsh(env, refresh = false) {
30325
30721
  }
30326
30722
 
30327
30723
  // src/guest/toolchains/languages/python.ts
30328
- import fs41 from "node:fs";
30329
- import path53 from "node:path";
30724
+ import fs43 from "node:fs";
30725
+ import path56 from "node:path";
30330
30726
  var installPython = async (pkg, spec) => {
30331
30727
  const version2 = await resolveCached(pkg + ":" + spec, async () => {
30332
30728
  const { versions } = await fetchJson(
@@ -30335,7 +30731,7 @@ var installPython = async (pkg, spec) => {
30335
30731
  return pickPackageVersion(versions, spec) ?? Promise.reject(new Error("No " + pkg + ' release matches "' + spec + '"'));
30336
30732
  });
30337
30733
  const dir = tool("python", pkg + "-" + version2);
30338
- const exe = path53.join(dir, "python.exe");
30734
+ const exe = path56.join(dir, "python.exe");
30339
30735
  if (!exists(exe)) {
30340
30736
  log("Downloading Python " + version2 + (pkg === "python2" ? " (Python 2, " : " (") + "~30 MB once) ...");
30341
30737
  await downloader.archive(
@@ -30344,32 +30740,32 @@ var installPython = async (pkg, spec) => {
30344
30740
  { locate: "python.exe", fileName: pkg + "." + version2 + ".zip" }
30345
30741
  );
30346
30742
  }
30347
- if (!exists(path53.join(dir, "Scripts", "pip.exe")) && !exists(path53.join(dir, "Scripts", "pip2.exe")))
30743
+ if (!exists(path56.join(dir, "Scripts", "pip.exe")) && !exists(path56.join(dir, "Scripts", "pip2.exe")))
30348
30744
  await execAsync(exe, ["-m", "ensurepip", "--default-pip"], { stdio: "ignore" });
30349
30745
  return dir;
30350
30746
  };
30351
- var shimDir = (dir) => duringSession() ? tool("shims", path53.basename(dir)) : tool("shims");
30747
+ var shimDir = (dir) => duringSession() ? tool("shims", path56.basename(dir)) : tool("shims");
30352
30748
  var shim = (folder, name, program, args = []) => {
30353
30749
  const fixed = [program, ...args];
30354
- fs41.writeFileSync(
30355
- path53.join(mkdirp(folder), name + ".cmd"),
30750
+ fs43.writeFileSync(
30751
+ path56.join(mkdirp(folder), name + ".cmd"),
30356
30752
  "@echo off\r\n" + fixed.map((a) => '"' + a + '"').join(" ") + " %*\r\n"
30357
30753
  );
30358
30754
  const sh = fixed.map((a) => "'" + a.replace(/\\/g, "/").replace(/'/g, "'\\''") + "'").join(" ");
30359
- fs41.writeFileSync(path53.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30755
+ fs43.writeFileSync(path56.join(folder, name), "#!/bin/sh\nexec " + sh + ' "$@"\n');
30360
30756
  };
30361
30757
  var shimPair = (folder, version2, dir) => {
30362
- const python = path53.join(dir, "python.exe");
30758
+ const python = path56.join(dir, "python.exe");
30363
30759
  shim(folder, "python" + version2, python);
30364
30760
  shim(folder, "pip" + version2, python, ["-m", "pip"]);
30365
30761
  };
30366
30762
  var pyLauncher = (folder, py3, py2) => {
30367
- const script = path53.join(mkdirp(folder), "py-launcher.py");
30368
- fs41.writeFileSync(
30763
+ const script = path56.join(mkdirp(folder), "py-launcher.py");
30764
+ fs43.writeFileSync(
30369
30765
  script,
30370
30766
  [
30371
30767
  "import subprocess, sys",
30372
- "PY3, PY2 = " + JSON.stringify(path53.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path53.join(py2, "python.exe") : null),
30768
+ "PY3, PY2 = " + JSON.stringify(path56.join(py3, "python.exe")) + ", " + JSON.stringify(py2 ? path56.join(py2, "python.exe") : null),
30373
30769
  "args = sys.argv[1:]",
30374
30770
  "exe = PY3",
30375
30771
  "if args and args[0].startswith('-2'):",
@@ -30381,7 +30777,7 @@ var pyLauncher = (folder, py3, py2) => {
30381
30777
  ""
30382
30778
  ].join("\n")
30383
30779
  );
30384
- shim(folder, "py", path53.join(py3, "python.exe"), [script]);
30780
+ shim(folder, "py", path56.join(py3, "python.exe"), [script]);
30385
30781
  };
30386
30782
  async function setupPython(env, config2, versions) {
30387
30783
  if (dryRun) {
@@ -30391,10 +30787,10 @@ async function setupPython(env, config2, versions) {
30391
30787
  const py3 = await installPython("python", versions.python.spec);
30392
30788
  const shims = shimDir(py3);
30393
30789
  shimPair(shims, "3", py3);
30394
- env.prepend.push(py3, path53.join(py3, "Scripts"), shims);
30790
+ env.prepend.push(py3, mkdirp(path56.join(py3, "Scripts")), shims);
30395
30791
  env.vars.PYTHONIOENCODING = "utf-8";
30396
30792
  env.summary.push(
30397
- "python: " + path53.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30793
+ "python: " + path56.basename(py3).replace("python-", "") + " (from " + versions.python.source + "; py works too)"
30398
30794
  );
30399
30795
  if (!config2.python2) {
30400
30796
  pyLauncher(shims, py3, null);
@@ -30403,16 +30799,16 @@ async function setupPython(env, config2, versions) {
30403
30799
  const py2 = await installPython("python2", "2.7");
30404
30800
  shimPair(shims, "2", py2);
30405
30801
  pyLauncher(shims, py3, py2);
30406
- env.summary.push("python2: " + path53.basename(py2).replace("python2-", ""));
30802
+ env.summary.push("python2: " + path56.basename(py2).replace("python2-", ""));
30407
30803
  }
30408
30804
 
30409
30805
  // src/guest/toolchains/languages/php.ts
30410
- import fs43 from "node:fs";
30411
- import path55 from "node:path";
30806
+ import fs45 from "node:fs";
30807
+ import path58 from "node:path";
30412
30808
 
30413
30809
  // src/guest/toolchains/native/vcruntime.ts
30414
- import fs42 from "node:fs";
30415
- import path54 from "node:path";
30810
+ import fs44 from "node:fs";
30811
+ import path57 from "node:path";
30416
30812
  var VC_REDIST = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
30417
30813
  var MICROSOFT_SIGNER = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US";
30418
30814
  var OK_EXIT_CODES = [0, 1638, 3010];
@@ -30422,8 +30818,8 @@ async function setupVcRuntime(env, summary = true) {
30422
30818
  log("(dry run) would install the Visual C++ runtime");
30423
30819
  return false;
30424
30820
  }
30425
- const system322 = path54.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30426
- const missing = !exists(path54.join(system322, "vcruntime140.dll")) || !exists(path54.join(system322, "msvcp140.dll"));
30821
+ const system322 = path57.join(process.env.WINDIR ?? "C:\\Windows", "System32");
30822
+ const missing = !exists(path57.join(system322, "vcruntime140.dll")) || !exists(path57.join(system322, "msvcp140.dll"));
30427
30823
  if (missing) {
30428
30824
  const installer = tool("vcredist", "vc_redist.x64.exe");
30429
30825
  if (!exists(installer)) {
@@ -30431,12 +30827,12 @@ async function setupVcRuntime(env, summary = true) {
30431
30827
  await downloadFile(VC_REDIST, installer);
30432
30828
  }
30433
30829
  if (signerOf(installer) !== MICROSOFT_SIGNER) {
30434
- fs42.rmSync(installer, { force: true });
30830
+ fs44.rmSync(installer, { force: true });
30435
30831
  throw new Error("vc_redist.x64.exe is not signed by Microsoft; deleted it (it is downloaded again next boot)");
30436
30832
  }
30437
30833
  log("Installing the Visual C++ runtime ...");
30438
30834
  const code = await spawnAsync(installer, ["/install", "/quiet", "/norestart"]);
30439
- if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path54.join(system322, "vcruntime140.dll")))
30835
+ if (!OK_EXIT_CODES.includes(code ?? -1) || !exists(path57.join(system322, "vcruntime140.dll")))
30440
30836
  throw new Error("the Visual C++ runtime installer failed (exit " + code + ")");
30441
30837
  }
30442
30838
  if (summary) env.summary.push("vc++ runtime: installed");
@@ -30474,16 +30870,16 @@ var phpBuild = async (spec) => {
30474
30870
  return { version: release.version, ...build.zip };
30475
30871
  };
30476
30872
  var writePhpIni = (home) => {
30477
- const ini = path55.join(home, "php.ini");
30478
- if (exists(ini) || !exists(path55.join(home, "php.ini-development"))) return;
30479
- let text = fs43.readFileSync(path55.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path55.join(home, "ext") + '"');
30480
- for (const ext of PHP_EXTENSIONS.filter((e) => exists(path55.join(home, "ext", "php_" + e + ".dll"))))
30873
+ const ini = path58.join(home, "php.ini");
30874
+ if (exists(ini) || !exists(path58.join(home, "php.ini-development"))) return;
30875
+ let text = fs45.readFileSync(path58.join(home, "php.ini-development"), "utf8").replace(/^;\s*extension_dir\s*=\s*"ext"/m, 'extension_dir = "' + path58.join(home, "ext") + '"');
30876
+ for (const ext of PHP_EXTENSIONS.filter((e) => exists(path58.join(home, "ext", "php_" + e + ".dll"))))
30481
30877
  text = text.replace(new RegExp("^;(extension=" + ext + ")\\s*$", "m"), "$1");
30482
- fs43.writeFileSync(ini + ".tmp", text);
30483
- fs43.renameSync(ini + ".tmp", ini);
30878
+ fs45.writeFileSync(ini + ".tmp", text);
30879
+ fs45.renameSync(ini + ".tmp", ini);
30484
30880
  };
30485
30881
  var shim2 = (env, name, command) => {
30486
- fs43.writeFileSync(path55.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30882
+ fs45.writeFileSync(path58.join(mkdirp(tool("shims")), name + ".cmd"), "@echo off\r\n" + command + " %*\r\n");
30487
30883
  env.prepend.push(tool("shims"));
30488
30884
  };
30489
30885
  var setupComposer = async (env, php) => {
@@ -30495,7 +30891,7 @@ var setupComposer = async (env, php) => {
30495
30891
  }
30496
30892
  const composerHome = tool("composer-home");
30497
30893
  env.vars.COMPOSER_HOME = composerHome;
30498
- env.prepend.push(path55.join(composerHome, "vendor", "bin"));
30894
+ env.prepend.push(path58.join(composerHome, "vendor", "bin"));
30499
30895
  shim2(env, "composer", '"' + php + '" "' + phar + '"');
30500
30896
  env.summary.push(
30501
30897
  "composer: " + (/\d+\.\d+\.\d+/.exec(execOutput(php, [phar, "--version", "--no-ansi"]))?.[0] ?? "installed")
@@ -30510,7 +30906,7 @@ async function setupPhp(env, config2) {
30510
30906
  await setupVcRuntime(env, false);
30511
30907
  const version2 = await resolveCached("php:" + wantedSpec.spec, async () => (await phpBuild(wantedSpec.spec)).version);
30512
30908
  const home = tool("php", version2);
30513
- if (!exists(path55.join(home, "php.exe"))) {
30909
+ if (!exists(path58.join(home, "php.exe"))) {
30514
30910
  const build = await phpBuild(version2);
30515
30911
  log("Downloading PHP " + version2 + " (~30 MB once) ...");
30516
30912
  await downloader.archive("https://windows.php.net/downloads/releases/" + build.path, home, {
@@ -30522,11 +30918,11 @@ async function setupPhp(env, config2) {
30522
30918
  writePhpIni(home);
30523
30919
  env.prepend.push(home);
30524
30920
  env.summary.push("php: " + version2 + " (from " + wantedSpec.source + ")");
30525
- if (config2.composer) await setupComposer(env, path55.join(home, "php.exe"));
30921
+ if (config2.composer) await setupComposer(env, path58.join(home, "php.exe"));
30526
30922
  }
30527
30923
 
30528
30924
  // src/guest/toolchains/languages/ruby.ts
30529
- import path56 from "node:path";
30925
+ import path59 from "node:path";
30530
30926
  var RUBY_ASSET = /^rubyinstaller-(\d+\.\d+\.\d+)-(\d+)-x64\.7z$/;
30531
30927
  var buildNumber = (asset) => Number(RUBY_ASSET.exec(asset.name)?.[2] ?? 0);
30532
30928
  var rubyBuilds = async () => {
@@ -30554,7 +30950,7 @@ async function setupRuby(env, config2) {
30554
30950
  async () => pickPackageVersion([...(await rubyBuilds()).keys()], wantedSpec.spec) ?? Promise.reject(new Error('No RubyInstaller build matches "' + wantedSpec.spec + '"'))
30555
30951
  );
30556
30952
  const home = tool("ruby", version2);
30557
- if (!exists(path56.join(home, "bin", "ruby.exe"))) {
30953
+ if (!exists(path59.join(home, "bin", "ruby.exe"))) {
30558
30954
  const asset = (await rubyBuilds()).get(version2);
30559
30955
  if (!asset) throw new Error("RubyInstaller " + version2 + " is no longer published");
30560
30956
  log("Downloading Ruby " + version2 + " (~100 MB once) ...");
@@ -30567,11 +30963,11 @@ async function setupRuby(env, config2) {
30567
30963
  }
30568
30964
  const gems = tool("ruby-gems", version2.split(".").slice(0, 2).join("."));
30569
30965
  Object.assign(env.vars, { GEM_HOME: gems, BUNDLE_USER_HOME: tool("bundle-home") });
30570
- env.prepend.push(path56.join(home, "bin"), path56.join(gems, "bin"));
30966
+ env.prepend.push(path59.join(home, "bin"), path59.join(gems, "bin"));
30571
30967
  env.summary.push(
30572
- "ruby: " + versionOf(path56.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
30968
+ "ruby: " + versionOf(path59.join(home, "bin", "ruby.exe")) + " (from " + wantedSpec.source + "; gems with C extensions need MSYS2, not included)"
30573
30969
  );
30574
- const gem = path56.join(home, "bin", "gem.cmd");
30970
+ const gem = path59.join(home, "bin", "gem.cmd");
30575
30971
  await installOnce(
30576
30972
  env,
30577
30973
  "gem@" + version2,
@@ -30583,9 +30979,9 @@ async function setupRuby(env, config2) {
30583
30979
  }
30584
30980
 
30585
30981
  // src/guest/toolchains/tools/vscode.ts
30586
- import fs44 from "node:fs";
30982
+ import fs46 from "node:fs";
30587
30983
  import os7 from "node:os";
30588
- import path57 from "node:path";
30984
+ import path60 from "node:path";
30589
30985
 
30590
30986
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
30591
30987
  var CharacterCodes;
@@ -30765,14 +31161,14 @@ var ParseErrorCode;
30765
31161
  var VERSION_MARKER = ".agent-sandbox-version";
30766
31162
  var desktopShortcut = (exe) => {
30767
31163
  if (!isWin) return;
30768
- const link = path57.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
31164
+ const link = path60.join(os7.homedir(), "Desktop", "Visual Studio Code.lnk");
30769
31165
  runScriptWithJson("new-shortcuts.ps1", "ListFile", [
30770
31166
  { link, target: exe, arguments: '"' + (process.env.AGENT_WORKSPACE ?? "") + '"' }
30771
31167
  ]);
30772
31168
  };
30773
31169
  async function setupVscode(env, refresh) {
30774
31170
  const root = tool("vscode");
30775
- const exe = path57.join(root, "Code.exe");
31171
+ const exe = path60.join(root, "Code.exe");
30776
31172
  if (dryRun) {
30777
31173
  log("(dry run) would provision VS Code");
30778
31174
  return;
@@ -30782,11 +31178,11 @@ async function setupVscode(env, refresh) {
30782
31178
  "https://update.code.visualstudio.com/api/update/win32-" + (arch === "arm64" ? "arm64" : "x64") + "-archive/stable/latest"
30783
31179
  );
30784
31180
  log("Downloading VS Code " + release.productVersion + " (~150 MB once) ...");
30785
- const keep = path57.join(root, "data");
31181
+ const keep = path60.join(root, "data");
30786
31182
  const parked = root + "-data";
30787
31183
  if (exists(keep)) {
30788
- fs44.rmSync(parked, { recursive: true, force: true });
30789
- fs44.renameSync(keep, parked);
31184
+ fs46.rmSync(parked, { recursive: true, force: true });
31185
+ fs46.renameSync(keep, parked);
30790
31186
  }
30791
31187
  try {
30792
31188
  await downloader.archive(release.url, root, {
@@ -30794,44 +31190,44 @@ async function setupVscode(env, refresh) {
30794
31190
  locate: "Code.exe",
30795
31191
  fileName: "vscode.zip"
30796
31192
  });
30797
- fs44.writeFileSync(path57.join(root, VERSION_MARKER), release.productVersion);
31193
+ fs46.writeFileSync(path60.join(root, VERSION_MARKER), release.productVersion);
30798
31194
  } finally {
30799
31195
  if (exists(parked)) {
30800
31196
  mkdirp(root);
30801
- fs44.rmSync(keep, { recursive: true, force: true });
30802
- fs44.renameSync(parked, keep);
31197
+ fs46.rmSync(keep, { recursive: true, force: true });
31198
+ fs46.renameSync(parked, keep);
30803
31199
  }
30804
31200
  }
30805
31201
  }
30806
- mkdirp(path57.join(root, "data"));
30807
- env.prepend.push(path57.join(root, "bin"));
31202
+ mkdirp(path60.join(root, "data"));
31203
+ env.prepend.push(path60.join(root, "bin"));
30808
31204
  desktopShortcut(exe);
30809
- const version2 = exists(path57.join(root, VERSION_MARKER)) ? fs44.readFileSync(path57.join(root, VERSION_MARKER), "utf8").trim() : "installed";
31205
+ const version2 = exists(path60.join(root, VERSION_MARKER)) ? fs46.readFileSync(path60.join(root, VERSION_MARKER), "utf8").trim() : "installed";
30810
31206
  env.summary.push("vscode: " + version2 + " (portable; run code . or use the desktop shortcut)");
30811
31207
  }
30812
31208
 
30813
31209
  // src/guest/toolchains/native/rust-extras.ts
30814
- import fs45 from "node:fs";
31210
+ import fs47 from "node:fs";
30815
31211
  import os8 from "node:os";
30816
- import path58 from "node:path";
31212
+ import path61 from "node:path";
30817
31213
  var cargoTarget = (targetDir) => {
30818
31214
  if (targetDir === "shared" || targetDir === "separate") return null;
30819
- if (targetDir === "local") return path58.join(localDir, "cargo-target");
31215
+ if (targetDir === "local") return path61.join(localDir, "cargo-target");
30820
31216
  return targetDir;
30821
31217
  };
30822
31218
  function cargoShim(env, rust) {
30823
- const real = path58.join(tool("rust", "cargo", "bin"), "cargo.exe");
31219
+ const real = path61.join(tool("rust", "cargo", "bin"), "cargo.exe");
30824
31220
  if (rust.targetDir !== "separate" || !exists(real)) return;
30825
31221
  const dir = mkdirp(tool("shims", "cargo"));
30826
- fs45.copyFileSync(ensureCompiled("cargoshim"), path58.join(dir, "cargo.exe"));
31222
+ fs47.copyFileSync(ensureCompiled("cargoshim"), path61.join(dir, "cargo.exe"));
30827
31223
  env.prepend.unshift(dir);
30828
31224
  env.vars.AGENT_REAL_CARGO = real;
30829
31225
  }
30830
31226
  function linkGate(env, rust, host) {
30831
31227
  const gcc = tool("mingw", "mingw64", "bin", "gcc.exe");
30832
31228
  if (!host.endsWith("-pc-windows-gnu") || !exists(gcc)) return;
30833
- const gate = path58.join(mkdirp(tool("shims")), "linkgate.exe");
30834
- fs45.copyFileSync(ensureCompiled("linkgate"), gate);
31229
+ const gate = path61.join(mkdirp(tool("shims")), "linkgate.exe");
31230
+ fs47.copyFileSync(ensureCompiled("linkgate"), gate);
30835
31231
  const memoryGb = os8.totalmem() / 1024 ** 3;
30836
31232
  const slots = rust.linkSlots === "auto" ? Math.max(2, Math.min(4, Math.floor(memoryGb / 8))) : rust.linkSlots;
30837
31233
  env.vars.AGENT_LINK_SLOTS = String(slots);
@@ -30839,18 +31235,18 @@ function linkGate(env, rust, host) {
30839
31235
  env.vars.CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = gate;
30840
31236
  const rustEnv = { ...process.env, RUSTUP_HOME: tool("rust", "rustup"), CARGO_HOME: tool("rust", "cargo") };
30841
31237
  const sysroot = rust.linker === "lld" ? execOutput(tool("rust", "cargo", "bin", "rustc.exe"), ["--print", "sysroot"], { env: rustEnv }) : "";
30842
- const lld = sysroot ? path58.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
30843
- if (lld && exists(path58.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
31238
+ const lld = sysroot ? path61.join(sysroot, "lib", "rustlib", host, "bin", "gcc-ld") : "";
31239
+ if (lld && exists(path61.join(lld, "ld.lld.exe"))) env.vars.AGENT_LLD_DIR = lld;
30844
31240
  env.summary.push(
30845
31241
  "rust linking: " + (env.vars.AGENT_LLD_DIR ? "lld" : "GNU ld") + ", at most " + env.vars.AGENT_LINK_SLOTS + " at once"
30846
31242
  );
30847
31243
  }
30848
31244
  function cargoDefaults(host) {
30849
31245
  const file3 = tool("rust", "cargo", "config.toml");
30850
- if (exists(file3) || !exists(path58.dirname(file3))) return;
31246
+ if (exists(file3) || !exists(path61.dirname(file3))) return;
30851
31247
  const jobs = Math.max(2, Math.min(4, Math.floor(os8.cpus().length / 4)));
30852
31248
  const gnu = host.endsWith("-gnu");
30853
- fs45.writeFileSync(
31249
+ fs47.writeFileSync(
30854
31250
  file3,
30855
31251
  [
30856
31252
  "# Written by windows-development-sandbox once; edit freely, it is never overwritten.",
@@ -30865,7 +31261,7 @@ function rustCaches(rust) {
30865
31261
  const target = cargoTarget(rust.targetDir);
30866
31262
  return {
30867
31263
  ...target ? { CARGO_TARGET_DIR: target } : {},
30868
- ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path58.join(dataDir, "cache", "sccache") }
31264
+ ...process.env.SCCACHE_DIR ? {} : { SCCACHE_DIR: path61.join(dataDir, "cache", "sccache") }
30869
31265
  };
30870
31266
  }
30871
31267
  function rustHost(config2) {
@@ -31169,21 +31565,21 @@ function cmdSet(env, names) {
31169
31565
  return names.filter((n) => env[n] !== void 0 && !/[\r\n]/.test(String(env[n]))).map((n) => '@set "' + n + "=" + String(env[n]).replace(/%/g, "%%") + '"');
31170
31566
  }
31171
31567
  function writeShell(spec, env, names) {
31172
- const dir = mkdirp(path59.join(localDir, "projects", spec.name));
31173
- fs46.writeFileSync(path59.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
31174
- fs46.writeFileSync(
31175
- path59.join(dir, "shell.cmd"),
31176
- ['@call "' + path59.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
31568
+ const dir = mkdirp(path62.join(localDir, "projects", spec.name));
31569
+ fs48.writeFileSync(path62.join(dir, "env.cmd"), [...cmdSet(env, [...names, "PATH"]), ""].join("\r\n"));
31570
+ fs48.writeFileSync(
31571
+ path62.join(dir, "shell.cmd"),
31572
+ ['@call "' + path62.join(dir, "env.cmd") + '"', '@cd /d "' + spec.workspace + '"', "@title " + spec.name, ""].join(
31177
31573
  "\r\n"
31178
31574
  )
31179
31575
  );
31180
- const bin = mkdirp(path59.join(localDir, "bin"));
31181
- fs46.writeFileSync(
31182
- path59.join(bin, "sbx-shell.cmd"),
31576
+ const bin = mkdirp(path62.join(localDir, "bin"));
31577
+ fs48.writeFileSync(
31578
+ path62.join(bin, "sbx-shell.cmd"),
31183
31579
  [
31184
- '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path59.join(localDir, "projects") + '" & exit /b 2)',
31185
- '@if not exist "' + path59.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
31186
- '@cmd /k ""' + path59.join(localDir, "projects") + '\\%~1\\shell.cmd""',
31580
+ '@if "%~1"=="" (echo Usage: sbx-shell ^<project^> ^(a terminal in that project with its tools^) & dir /b "' + path62.join(localDir, "projects") + '" & exit /b 2)',
31581
+ '@if not exist "' + path62.join(localDir, "projects") + '\\%~1\\shell.cmd" (echo No project %~1 in this sandbox. & exit /b 2)',
31582
+ '@cmd /k ""' + path62.join(localDir, "projects") + '\\%~1\\shell.cmd""',
31187
31583
  ""
31188
31584
  ].join("\r\n")
31189
31585
  );
@@ -31236,10 +31632,10 @@ async function setUp(spec, say) {
31236
31632
  }
31237
31633
  )
31238
31634
  );
31239
- tools.prepend.push(path59.join(localDir, "bin"));
31635
+ tools.prepend.push(path62.join(localDir, "bin"));
31240
31636
  const env = agentEnv(tools, { workspace: spec.workspace, project: spec.name, base });
31241
- const specFile = path59.join(mkdirp(path59.join(localDir, "projects", spec.name)), "project.json");
31242
- fs46.writeFileSync(specFile, JSON.stringify(spec));
31637
+ const specFile = path62.join(mkdirp(path62.join(localDir, "projects", spec.name)), "project.json");
31638
+ fs48.writeFileSync(specFile, JSON.stringify(spec));
31243
31639
  env.AGENT_PROJECT_FILE = specFile;
31244
31640
  addMachineEnvironment(tools.vars, [...tools.prepend, ...tools.append], true);
31245
31641
  try {
@@ -31326,7 +31722,7 @@ function execCommand(req) {
31326
31722
  respond(req.id, { ok: false, message: "Folder is not inside the sandbox workspace: " + req.cwd });
31327
31723
  return;
31328
31724
  }
31329
- const env = provisioner.provisionedFor(req.cwd)?.env ?? process.env;
31725
+ const env = withRegistryPath(provisioner.provisionedFor(req.cwd)?.env ?? process.env);
31330
31726
  const child = spawn5(
31331
31727
  SYSTEM.cmd(),
31332
31728
  ["/d", "/s", "/c", '"chcp 65001>nul & ' + req.command.map(quoteForCmd).join(" ") + '"'],
@@ -31356,7 +31752,7 @@ function execCommand(req) {
31356
31752
  }
31357
31753
 
31358
31754
  // src/guest/daemon/sessions.ts
31359
- import path64 from "node:path";
31755
+ import path67 from "node:path";
31360
31756
  import crypto4 from "node:crypto";
31361
31757
  import { spawn as spawn7 } from "node:child_process";
31362
31758
 
@@ -31429,7 +31825,7 @@ async function sendControl(endpoint, type) {
31429
31825
  }
31430
31826
 
31431
31827
  // src/guest/sessions/cmdline.ts
31432
- import path60 from "node:path";
31828
+ import path63 from "node:path";
31433
31829
  var quoted = (arg) => '"' + arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
31434
31830
  function quoteArg(arg) {
31435
31831
  return arg !== "" && !/[\s"]/.test(arg) ? arg : quoted(arg);
@@ -31443,12 +31839,12 @@ function cmdArgs(args) {
31443
31839
  }).join("");
31444
31840
  }
31445
31841
  function commandLine(file3, args) {
31446
- return path60.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
31842
+ return path63.win32.basename(file3).toLowerCase() === "cmd.exe" ? [quoteArg(file3), cmdArgs(args)].filter(Boolean).join(" ") : [file3, ...args].map(quoteArg).join(" ");
31447
31843
  }
31448
31844
 
31449
31845
  // src/guest/sessions/pty-host.ts
31450
- import fs47 from "node:fs";
31451
- import path61 from "node:path";
31846
+ import fs49 from "node:fs";
31847
+ import path64 from "node:path";
31452
31848
  import { spawn as spawn6 } from "node:child_process";
31453
31849
  function ensurePtyHost() {
31454
31850
  return ensureCompiled("ptyhost");
@@ -31467,18 +31863,18 @@ async function waitForPtyHost(child, port, timeoutMs) {
31467
31863
  throw new Error("the session host did not start listening on port " + port);
31468
31864
  }
31469
31865
  function ptyHostLog(id) {
31470
- return path61.join(logsDir, "ptyhost-" + id + ".log");
31866
+ return path64.join(logsDir, "ptyhost-" + id + ".log");
31471
31867
  }
31472
31868
  function ptyHostLogTail(id, lines = 12) {
31473
31869
  try {
31474
- return fs47.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
31870
+ return fs49.readFileSync(ptyHostLog(id), "utf8").trim().split(/\r?\n/).slice(-lines).join("\n");
31475
31871
  } catch {
31476
31872
  return "";
31477
31873
  }
31478
31874
  }
31479
31875
  var conptyDll = () => {
31480
- const dll = path61.join(toolsDir, "conpty", "conpty.dll");
31481
- return session.provisioning.conpty?.enabled !== false && fs47.existsSync(dll) && fs47.existsSync(path61.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
31876
+ const dll = path64.join(toolsDir, "conpty", "conpty.dll");
31877
+ return session.provisioning.conpty?.enabled !== false && fs49.existsSync(dll) && fs49.existsSync(path64.join(toolsDir, "conpty", "OpenConsole.exe")) ? dll : null;
31482
31878
  };
31483
31879
  function startPtyHost(o) {
31484
31880
  const env = { ...o.env, PTYHOST_BIND: o.remote ? "any" : "loopback" };
@@ -31493,8 +31889,8 @@ function startPtyHost(o) {
31493
31889
  }
31494
31890
 
31495
31891
  // src/guest/agents/agent-installer.ts
31496
- import fs48 from "node:fs";
31497
- import path62 from "node:path";
31892
+ import fs50 from "node:fs";
31893
+ import path65 from "node:path";
31498
31894
 
31499
31895
  // src/guest/agents/profile-links.ts
31500
31896
  var profileRoot = () => process.env.USERPROFILE ?? "";
@@ -31516,19 +31912,11 @@ function linkHarnessProfile(name, harness) {
31516
31912
  }
31517
31913
 
31518
31914
  // src/guest/agents/agent-installer.ts
31519
- function agentPaths(name, harness) {
31520
- const dir = path62.join(toolsDir, "agents", name);
31521
- const exe = harness.hostExecutable ?? (harness.uvBin ? harness.uvBin + ".exe" : null);
31522
- return {
31523
- dir,
31524
- exe: exe ? path62.join(dir, exe) : null,
31525
- cmd: harness.npmBin ? path62.join(dir, harness.npmBin + ".cmd") : null
31526
- };
31527
- }
31915
+ var agentPaths2 = (name, harness) => agentPaths(toolsDir, name, harness);
31528
31916
  async function installViaNpm(name, harness, dir, env) {
31529
31917
  if (!harness.npmPackage)
31530
31918
  throw new Error("No npmPackage configured for " + name + " and no host executable was available.");
31531
- const npmCli = path62.join(path62.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
31919
+ const npmCli = path65.join(path65.dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
31532
31920
  const args = [npmCli, "install", "--global", "--prefix", dir, harness.npmPackage, "--no-fund", "--no-audit"];
31533
31921
  log("Installing " + harness.npmPackage + " (this can take a minute)...");
31534
31922
  if (dryRun) {
@@ -31539,7 +31927,7 @@ async function installViaNpm(name, harness, dir, env) {
31539
31927
  await execAsync(process.execPath, args, { env });
31540
31928
  }
31541
31929
  async function installViaUv(name, harness, dir, env) {
31542
- const uv = path62.join(toolsDir, "uv", "uv.exe");
31930
+ const uv = path65.join(toolsDir, "uv", "uv.exe");
31543
31931
  log("Installing " + harness.uvPackage + " with uv (this can take a minute)...");
31544
31932
  if (dryRun) {
31545
31933
  log("(dry run) uv tool install " + harness.uvPackage);
@@ -31554,8 +31942,8 @@ async function installViaUv(name, harness, dir, env) {
31554
31942
  });
31555
31943
  }
31556
31944
  function putOnPath(dir, env) {
31557
- const parts2 = (env.PATH ?? "").split(path62.delimiter);
31558
- if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path62.delimiter);
31945
+ const parts2 = (env.PATH ?? "").split(path65.delimiter);
31946
+ if (!parts2.some((p) => p.toLowerCase() === dir.toLowerCase())) env.PATH = [...parts2, dir].join(path65.delimiter);
31559
31947
  addMachineEnvironment({}, [dir], true);
31560
31948
  }
31561
31949
  var AgentInstaller = class {
@@ -31569,13 +31957,13 @@ var AgentInstaller = class {
31569
31957
  const current = this.installing.get(name);
31570
31958
  if (current) return current;
31571
31959
  linkHarnessProfile(name, harness);
31572
- const work = this.install(name, harness, env, refresh).then(() => putOnPath(agentPaths(name, harness).dir, env)).finally(() => this.installing.delete(name));
31960
+ const work = this.install(name, harness, env, refresh).then(() => putOnPath(agentPaths2(name, harness).dir, env)).finally(() => this.installing.delete(name));
31573
31961
  this.installing.set(name, work);
31574
31962
  return work;
31575
31963
  }
31576
31964
  /** Program + arguments that start the agent (an npm .cmd shim has to go through cmd.exe). */
31577
31965
  resolveLaunch(name, harness) {
31578
- const p = agentPaths(name, harness);
31966
+ const p = agentPaths2(name, harness);
31579
31967
  if (p.exe && exists(p.exe)) return { file: p.exe, args: [] };
31580
31968
  if (p.cmd && exists(p.cmd))
31581
31969
  return isWin ? { file: SYSTEM.cmd(), args: ["/d", "/c", p.cmd] } : { file: p.cmd, args: [] };
@@ -31588,7 +31976,7 @@ var AgentInstaller = class {
31588
31976
  return harness.uvPackage && !harness.npmPackage ? "uv" : "npm";
31589
31977
  }
31590
31978
  async install(name, harness, env, refresh) {
31591
- const p = agentPaths(name, harness);
31979
+ const p = agentPaths2(name, harness);
31592
31980
  const cached2 = p.exe !== null && exists(p.exe) || p.cmd !== null && exists(p.cmd);
31593
31981
  if (cached2 && !refresh) {
31594
31982
  log(name + " already cached in persistent storage.");
@@ -31596,9 +31984,9 @@ var AgentInstaller = class {
31596
31984
  }
31597
31985
  mkdirp(p.dir);
31598
31986
  if (this.sourceOf(name, harness) === "host") {
31599
- const source = path62.join(hostToolsDir, "agents", name, harness.hostExecutable);
31987
+ const source = path65.join(hostToolsDir, "agents", name, harness.hostExecutable);
31600
31988
  if (exists(source) && p.exe) {
31601
- fs48.copyFileSync(source, p.exe);
31989
+ fs50.copyFileSync(source, p.exe);
31602
31990
  log("Copied " + name + " from this PC: " + source);
31603
31991
  return;
31604
31992
  }
@@ -31619,22 +32007,22 @@ function guestAddresses() {
31619
32007
  }
31620
32008
 
31621
32009
  // src/guest/sessions/conversation.ts
31622
- import fs49 from "node:fs";
31623
- import path63 from "node:path";
32010
+ import fs51 from "node:fs";
32011
+ import path66 from "node:path";
31624
32012
  var MAX_FILES = 2e3;
31625
32013
  function conversationFiles(claudeDir2, cwd) {
31626
32014
  const names = /* @__PURE__ */ new Set([projectFolderName(cwd), projectFolderName(sandboxFolder(cwd))]);
31627
32015
  return [...names].flatMap((name) => {
31628
- const dir = path63.join(claudeDir2, "projects", name);
32016
+ const dir = path66.join(claudeDir2, "projects", name);
31629
32017
  let entries2;
31630
32018
  try {
31631
- entries2 = fs49.readdirSync(dir);
32019
+ entries2 = fs51.readdirSync(dir);
31632
32020
  } catch {
31633
32021
  return [];
31634
32022
  }
31635
32023
  return entries2.filter((e) => e.endsWith(".jsonl") && isConversationId(e.slice(0, -".jsonl".length))).slice(0, MAX_FILES).flatMap((e) => {
31636
32024
  try {
31637
- return [{ id: e.slice(0, -".jsonl".length), createdMs: fs49.statSync(path63.join(dir, e)).birthtimeMs }];
32025
+ return [{ id: e.slice(0, -".jsonl".length), createdMs: fs51.statSync(path66.join(dir, e)).birthtimeMs }];
31638
32026
  } catch {
31639
32027
  return [];
31640
32028
  }
@@ -31662,6 +32050,7 @@ var IdleShutdown = class {
31662
32050
  if (!this.idle()) return;
31663
32051
  log("Headless sandbox has no sessions left; shutting down.");
31664
32052
  safely("claude-mem save", saveClaudeMem);
32053
+ safely("agent databases save", saveLocalState);
31665
32054
  spawnSync6(SYSTEM.shutdown(), ["/s", "/t", "5"], { windowsHide: true });
31666
32055
  }, GRACE_MS);
31667
32056
  }
@@ -31672,8 +32061,8 @@ var IdleShutdown = class {
31672
32061
 
31673
32062
  // src/guest/daemon/sessions.ts
31674
32063
  function terminalTab(id, title, cwd) {
31675
- const view = [process.execPath, path64.join(path64.dirname(process.argv[1]), "view.js"), id];
31676
- const wt = path64.join(toolsDir, "terminal", "wt.exe");
32064
+ const view = [process.execPath, path67.join(path67.dirname(process.argv[1]), "view.js"), id];
32065
+ const wt = path67.join(toolsDir, "terminal", "wt.exe");
31677
32066
  if (exists(wt))
31678
32067
  spawn7(wt, ["-w", "0", "nt", "--title", title, "-d", cwd, ...view], { detached: true, stdio: "ignore" }).unref();
31679
32068
  else spawn7(SYSTEM.cmd(), ["/d", "/c", "start", title, ...view], { detached: true, stdio: "ignore", cwd }).unref();
@@ -31702,7 +32091,7 @@ var launchPtyHost = async (req, remote, env, say) => {
31702
32091
  rows: 32,
31703
32092
  id: req.id,
31704
32093
  cwd: req.cwd,
31705
- env: { ...env, ...harness.environment },
32094
+ env: { ...withRegistryPath(env), ...harness.environment },
31706
32095
  remote,
31707
32096
  command: commandLine(launch.file, [...base, ...req.args]),
31708
32097
  restartCommand: commandLine(launch.file, [...base, ...harness.resumeArguments ?? []])
@@ -31712,7 +32101,7 @@ var launchPtyHost = async (req, remote, env, say) => {
31712
32101
  } catch (e) {
31713
32102
  const tail = ptyHostLogTail(req.id);
31714
32103
  throw new Error(
31715
- errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path64.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
32104
+ errMsg(e) + (tail ? ". From its log:\n" + tail : "") + "\nLog: " + path67.join(dataDir, "logs", "ptyhost-" + req.id + ".log")
31716
32105
  );
31717
32106
  }
31718
32107
  return { child, port, token };
@@ -31770,7 +32159,7 @@ var SessionManager = class {
31770
32159
  };
31771
32160
  this.starting++;
31772
32161
  if (req.id !== session.launchId && process.env.AGENT_NO_TABS !== "1")
31773
- safely("terminal tab", () => terminalTab(req.id, req.harness + " " + path64.basename(req.cwd), req.cwd));
32162
+ safely("terminal tab", () => terminalTab(req.id, req.harness + " " + path67.basename(req.cwd), req.cwd));
31774
32163
  try {
31775
32164
  const place = await placeFor(req, say);
31776
32165
  const remote = session.networking && session.attach.enabled;
@@ -31877,6 +32266,7 @@ var SessionManager = class {
31877
32266
  );
31878
32267
  else safely("post-agent hooks", () => runHooks("post-agent", process.env));
31879
32268
  safely("claude-mem save", saveClaudeMem);
32269
+ safely("agent databases save", saveLocalState);
31880
32270
  this.idle.check();
31881
32271
  }
31882
32272
  };
@@ -31900,15 +32290,18 @@ var Daemon = class {
31900
32290
  tick() {
31901
32291
  const { valid, invalid } = run.scanRequests();
31902
32292
  for (const file3 of invalid)
31903
- safely("removing an invalid request", () => fs50.rmSync(file3, { recursive: true, force: true }));
32293
+ safely("removing an invalid request", () => fs52.rmSync(file3, { recursive: true, force: true }));
31904
32294
  for (const req of valid) {
31905
- safely("claiming a request", () => fs50.rmSync(run.requestFile(req.id), { force: true }));
32295
+ safely("claiming a request", () => fs52.rmSync(run.requestFile(req.id), { force: true }));
31906
32296
  if (run.readSession(req.id)) continue;
31907
- void Promise.resolve(this.handle(req)).catch((e) => respond(req.id, { ok: false, message: errMsg(e) }));
32297
+ void Promise.resolve(this.handle(withRequestSecrets(req))).catch(
32298
+ (e) => respond(req.id, { ok: false, message: errMsg(e) })
32299
+ );
31908
32300
  }
31909
32301
  if (Date.now() - this.lastMemSave > MEM_SAVE_MS) {
31910
32302
  this.lastMemSave = Date.now();
31911
32303
  safely("claude-mem save", saveClaudeMem);
32304
+ safely("agent databases save", saveLocalState);
31912
32305
  }
31913
32306
  }
31914
32307
  handle(req) {
@@ -31930,6 +32323,7 @@ var Daemon = class {
31930
32323
  // src/guest/entries/daemon.ts
31931
32324
  process.on("uncaughtException", (e) => warn("daemon: unexpected error (continuing): " + (e.stack ?? errMsg(e))));
31932
32325
  process.on("unhandledRejection", (e) => warn("daemon: unexpected error (continuing): " + errMsg(e)));
32326
+ adoptBootSecrets();
31933
32327
  log("Session daemon started (pid " + process.pid + ").");
31934
32328
  safely("port forwards", startRelays);
31935
32329
  safely("audit", startProcessCollector);