windows-development-sandbox 1.5.0 → 1.9.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 (709) hide show
  1. package/README.md +1 -0
  2. package/config.example.json +27 -1
  3. package/dist/app/context.d.ts +8 -0
  4. package/dist/app/context.js +12 -0
  5. package/dist/app/features/defs.d.ts +322 -0
  6. package/dist/app/features/defs.js +28 -0
  7. package/dist/app/features/sandbox/index.d.ts +2 -0
  8. package/dist/app/features/sandbox/index.js +3 -0
  9. package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
  10. package/dist/app/features/sandbox/sandbox.def.js +245 -0
  11. package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
  12. package/dist/app/features/sandbox/sandbox.run.js +98 -0
  13. package/dist/app/features/sessions/index.d.ts +2 -0
  14. package/dist/app/features/sessions/index.js +3 -0
  15. package/dist/app/features/sessions/sessions.def.d.ts +141 -0
  16. package/dist/app/features/sessions/sessions.def.js +176 -0
  17. package/dist/app/features/sessions/sessions.run.d.ts +39 -0
  18. package/dist/app/features/sessions/sessions.run.js +58 -0
  19. package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +4 -0
  20. package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +40 -46
  21. package/dist/app/features/settings/index.d.ts +5 -0
  22. package/dist/app/features/settings/index.js +6 -0
  23. package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
  24. package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
  25. package/dist/app/features/settings/settings-rows.d.ts +35 -0
  26. package/dist/app/features/settings/settings-rows.js +94 -0
  27. package/dist/app/features/settings/settings.def.d.ts +157 -0
  28. package/dist/app/features/settings/settings.def.js +179 -0
  29. package/dist/app/features/settings/settings.run.d.ts +67 -0
  30. package/dist/app/features/settings/settings.run.js +84 -0
  31. package/dist/app/kernel/define.d.ts +143 -0
  32. package/dist/app/kernel/define.js +42 -0
  33. package/dist/app/kernel/errors.d.ts +34 -0
  34. package/dist/app/kernel/errors.js +45 -0
  35. package/dist/app/kernel/fields.d.ts +70 -0
  36. package/dist/app/kernel/fields.js +243 -0
  37. package/dist/app/kernel/index.d.ts +8 -0
  38. package/dist/app/kernel/index.js +10 -0
  39. package/dist/app/kernel/io.d.ts +193 -0
  40. package/dist/app/kernel/io.js +126 -0
  41. package/dist/app/kernel/rpc.d.ts +156 -0
  42. package/dist/app/kernel/rpc.js +47 -0
  43. package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +9 -0
  44. package/dist/{cli/menu/settings → app/kernel}/schema-node.js +26 -0
  45. package/dist/app/kernel/text.d.ts +6 -0
  46. package/dist/app/kernel/text.js +57 -0
  47. package/dist/app/kernel/view.d.ts +146 -0
  48. package/dist/app/kernel/view.js +28 -0
  49. package/dist/app/registry.d.ts +10 -0
  50. package/dist/app/registry.js +50 -0
  51. package/dist/cli/args.d.ts +18 -2
  52. package/dist/cli/args.js +101 -24
  53. package/dist/cli/commands/accounts.js +45 -17
  54. package/dist/cli/commands/context.d.ts +2 -0
  55. package/dist/cli/commands/context.js +9 -2
  56. package/dist/cli/commands/data/clean.js +32 -9
  57. package/dist/cli/commands/engine.d.ts +2 -0
  58. package/dist/cli/commands/engine.js +60 -0
  59. package/dist/cli/commands/index.d.ts +2 -1
  60. package/dist/cli/commands/index.js +2 -1
  61. package/dist/cli/commands/launch/add-root.d.ts +3 -2
  62. package/dist/cli/commands/launch/add-root.js +11 -10
  63. package/dist/cli/commands/launch/launch.js +102 -9
  64. package/dist/cli/commands/launch/prepare.js +6 -4
  65. package/dist/cli/commands/launch/running.js +2 -1
  66. package/dist/cli/commands/launch/summary.d.ts +2 -0
  67. package/dist/cli/commands/maintenance/audit.js +1 -1
  68. package/dist/cli/commands/maintenance/clean.d.ts +1 -1
  69. package/dist/cli/commands/maintenance/clean.js +17 -3
  70. package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
  71. package/dist/cli/commands/maintenance/config-share.js +80 -0
  72. package/dist/cli/commands/maintenance/config.d.ts +1 -1
  73. package/dist/cli/commands/maintenance/config.js +38 -10
  74. package/dist/cli/commands/maintenance/doctor.d.ts +1 -1
  75. package/dist/cli/commands/maintenance/doctor.js +2 -4
  76. package/dist/cli/commands/maintenance/logs.js +14 -0
  77. package/dist/cli/commands/maintenance/migrate.d.ts +2 -1
  78. package/dist/cli/commands/maintenance/migrate.js +19 -4
  79. package/dist/cli/commands/maintenance/sync.js +2 -0
  80. package/dist/cli/commands/maintenance/update.d.ts +2 -0
  81. package/dist/cli/commands/maintenance/update.js +27 -4
  82. package/dist/cli/commands/projects/here.js +12 -7
  83. package/dist/cli/commands/projects/projects.js +26 -17
  84. package/dist/cli/commands/registry.js +10 -7
  85. package/dist/cli/commands/repair/checks/agents.d.ts +2 -0
  86. package/dist/cli/commands/repair/checks/agents.js +70 -0
  87. package/dist/cli/commands/repair/checks/common.d.ts +8 -0
  88. package/dist/cli/commands/repair/checks/common.js +22 -0
  89. package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
  90. package/dist/cli/commands/repair/checks/contained.js +139 -0
  91. package/dist/cli/commands/repair/checks/data.d.ts +2 -0
  92. package/dist/cli/commands/repair/checks/data.js +241 -0
  93. package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
  94. package/dist/cli/commands/repair/checks/hcs.js +28 -0
  95. package/dist/cli/commands/repair/checks/index.d.ts +2 -0
  96. package/dist/cli/commands/repair/checks/index.js +24 -0
  97. package/dist/cli/commands/repair/checks/install.d.ts +5 -0
  98. package/dist/cli/commands/repair/checks/install.js +318 -0
  99. package/dist/cli/commands/repair/checks/machine.d.ts +2 -0
  100. package/dist/cli/commands/repair/checks/machine.js +232 -0
  101. package/dist/cli/commands/repair/checks/network.d.ts +6 -0
  102. package/dist/cli/commands/repair/checks/network.js +60 -0
  103. package/dist/cli/commands/repair/checks/pc.d.ts +4 -0
  104. package/dist/cli/commands/repair/checks/pc.js +86 -0
  105. package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
  106. package/dist/cli/commands/repair/checks/sandbox.js +282 -0
  107. package/dist/cli/commands/repair/checks/settings.d.ts +2 -0
  108. package/dist/cli/commands/repair/checks/settings.js +169 -0
  109. package/dist/cli/commands/repair/checks/vpn.d.ts +2 -0
  110. package/dist/cli/commands/repair/checks/vpn.js +78 -0
  111. package/dist/cli/commands/repair/engine.d.ts +32 -0
  112. package/dist/cli/commands/repair/engine.js +127 -0
  113. package/dist/cli/commands/repair/env.d.ts +7 -0
  114. package/dist/cli/commands/repair/env.js +50 -0
  115. package/dist/cli/commands/repair/index.d.ts +1 -9
  116. package/dist/cli/commands/repair/index.js +2 -54
  117. package/dist/cli/commands/repair/log.d.ts +17 -0
  118. package/dist/cli/commands/repair/log.js +82 -0
  119. package/dist/cli/commands/repair/printer.d.ts +32 -0
  120. package/dist/cli/commands/repair/printer.js +132 -0
  121. package/dist/cli/commands/repair/run.d.ts +33 -0
  122. package/dist/cli/commands/repair/run.js +133 -0
  123. package/dist/cli/commands/repair/types.d.ts +97 -9
  124. package/dist/cli/commands/repair/types.js +11 -7
  125. package/dist/cli/commands/resume.js +2 -2
  126. package/dist/cli/commands/sessions/index.d.ts +0 -4
  127. package/dist/cli/commands/sessions/index.js +3 -7
  128. package/dist/cli/commands/setup/index.d.ts +5 -0
  129. package/dist/cli/commands/setup/index.js +25 -1
  130. package/dist/cli/commands/shared-use.d.ts +5 -2
  131. package/dist/cli/commands/shared-use.js +11 -8
  132. package/dist/cli/commands/storage/contained.d.ts +3 -0
  133. package/dist/cli/commands/storage/contained.js +179 -0
  134. package/dist/cli/commands/storage/index.d.ts +2 -0
  135. package/dist/cli/commands/storage/index.js +2 -0
  136. package/dist/cli/commands/storage/offer.d.ts +3 -0
  137. package/dist/cli/commands/storage/offer.js +91 -0
  138. package/dist/cli/commands/storage/storage.d.ts +8 -0
  139. package/dist/cli/commands/storage/storage.js +179 -0
  140. package/dist/cli/commands/user-config.js +2 -2
  141. package/dist/cli/commands/vpn.d.ts +4 -0
  142. package/dist/cli/commands/vpn.js +91 -0
  143. package/dist/cli/commands/web.d.ts +4 -0
  144. package/dist/cli/commands/web.js +97 -0
  145. package/dist/cli/history.js +1 -1
  146. package/dist/cli/index.js +48 -4
  147. package/dist/cli/manifest.d.ts +339 -97
  148. package/dist/cli/manifest.js +222 -67
  149. package/dist/cli/menu/add-agent.d.ts +47 -0
  150. package/dist/cli/menu/add-agent.js +168 -0
  151. package/dist/cli/menu/apps.d.ts +38 -3
  152. package/dist/cli/menu/apps.js +80 -5
  153. package/dist/cli/menu/command-fields.d.ts +18 -0
  154. package/dist/cli/menu/command-fields.js +61 -0
  155. package/dist/cli/menu/command-form.d.ts +22 -0
  156. package/dist/cli/menu/command-form.js +169 -46
  157. package/dist/cli/menu/data-folder.d.ts +18 -0
  158. package/dist/cli/menu/data-folder.js +99 -0
  159. package/dist/cli/menu/io-menu.d.ts +29 -0
  160. package/dist/cli/menu/io-menu.js +126 -0
  161. package/dist/cli/menu/live.d.ts +27 -0
  162. package/dist/cli/menu/live.js +69 -0
  163. package/dist/cli/menu/memory.d.ts +19 -0
  164. package/dist/cli/menu/memory.js +53 -0
  165. package/dist/cli/menu/menu.d.ts +11 -2
  166. package/dist/cli/menu/menu.js +36 -15
  167. package/dist/cli/menu/pages/accounts-page.js +55 -24
  168. package/dist/cli/menu/pages/agents-page.d.ts +68 -0
  169. package/dist/cli/menu/pages/agents-page.js +345 -0
  170. package/dist/cli/menu/pages/apps-page.d.ts +3 -1
  171. package/dist/cli/menu/pages/apps-page.js +20 -4
  172. package/dist/cli/menu/pages/list-page.d.ts +43 -3
  173. package/dist/cli/menu/pages/list-page.js +146 -12
  174. package/dist/cli/menu/pages/maintenance-page.d.ts +9 -5
  175. package/dist/cli/menu/pages/maintenance-page.js +172 -85
  176. package/dist/cli/menu/pages/sandbox-page.d.ts +7 -6
  177. package/dist/cli/menu/pages/sandbox-page.js +117 -120
  178. package/dist/cli/menu/pages/scopes.d.ts +1 -1
  179. package/dist/cli/menu/pages/sessions-page.d.ts +6 -8
  180. package/dist/cli/menu/pages/sessions-page.js +22 -75
  181. package/dist/cli/menu/pages/settings-page.d.ts +10 -14
  182. package/dist/cli/menu/pages/settings-page.js +95 -102
  183. package/dist/cli/menu/render-view.d.ts +28 -0
  184. package/dist/cli/menu/render-view.js +112 -0
  185. package/dist/cli/menu/settings/ask-path.d.ts +14 -0
  186. package/dist/cli/menu/settings/ask-path.js +14 -0
  187. package/dist/cli/menu/settings/collections/collection-editor.d.ts +8 -2
  188. package/dist/cli/menu/settings/collections/collection-editor.js +12 -8
  189. package/dist/cli/menu/settings/collections/map-editor.js +5 -1
  190. package/dist/cli/menu/settings/collections/object-list-editor.js +2 -2
  191. package/dist/cli/menu/settings/collections/object-map-editor.js +2 -2
  192. package/dist/cli/menu/settings/collections/string-list-editor.d.ts +10 -1
  193. package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
  194. package/dist/cli/menu/settings/draft.d.ts +1 -1
  195. package/dist/cli/menu/settings/format.d.ts +1 -3
  196. package/dist/cli/menu/settings/format.js +6 -36
  197. package/dist/cli/menu/settings/index.d.ts +1 -3
  198. package/dist/cli/menu/settings/index.js +3 -3
  199. package/dist/cli/menu/settings/object-editor.d.ts +6 -2
  200. package/dist/cli/menu/settings/object-editor.js +15 -4
  201. package/dist/cli/menu/settings/share.d.ts +36 -0
  202. package/dist/cli/menu/settings/share.js +131 -0
  203. package/dist/cli/menu/settings/value-editor.d.ts +10 -1
  204. package/dist/cli/menu/settings/value-editor.js +99 -63
  205. package/dist/cli/menu/several.js +7 -5
  206. package/dist/cli/menu/share-settings.d.ts +21 -0
  207. package/dist/cli/menu/share-settings.js +112 -0
  208. package/dist/cli/menu/shell.d.ts +53 -10
  209. package/dist/cli/menu/shell.js +115 -10
  210. package/dist/cli/menu/views.d.ts +7 -0
  211. package/dist/cli/menu/views.js +11 -0
  212. package/dist/cli/menu/vpn-login.d.ts +16 -0
  213. package/dist/cli/menu/vpn-login.js +74 -0
  214. package/dist/cli/operations/handler.d.ts +6 -0
  215. package/dist/cli/operations/handler.js +61 -0
  216. package/dist/cli/operations/index.d.ts +4 -0
  217. package/dist/cli/operations/index.js +5 -0
  218. package/dist/cli/operations/input.d.ts +6 -0
  219. package/dist/cli/operations/input.js +37 -0
  220. package/dist/cli/operations/io-cli.d.ts +7 -0
  221. package/dist/cli/operations/io-cli.js +62 -0
  222. package/dist/cli/operations/spec.d.ts +18 -0
  223. package/dist/cli/operations/spec.js +108 -0
  224. package/dist/cli/output/colors.d.ts +2 -2
  225. package/dist/cli/output/colors.js +2 -11
  226. package/dist/cli/output/index.d.ts +1 -0
  227. package/dist/cli/output/index.js +1 -0
  228. package/dist/cli/output/print.d.ts +5 -1
  229. package/dist/cli/output/print.js +15 -4
  230. package/dist/cli/output/progress.d.ts +15 -0
  231. package/dist/cli/output/progress.js +44 -0
  232. package/dist/cli/output/render-view.d.ts +4 -0
  233. package/dist/cli/output/render-view.js +63 -0
  234. package/dist/cli/services/accounts-service.d.ts +2 -0
  235. package/dist/cli/services/accounts-service.js +2 -2
  236. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  237. package/dist/cli/services/agent-commands-service.js +11 -2
  238. package/dist/cli/services/health-service.d.ts +0 -6
  239. package/dist/cli/services/health-service.js +5 -42
  240. package/dist/cli/services/index.d.ts +3 -1
  241. package/dist/cli/services/index.js +3 -1
  242. package/dist/cli/services/logs-service.js +4 -3
  243. package/dist/cli/services/migrate-service.js +1 -1
  244. package/dist/cli/services/update-service.d.ts +2 -0
  245. package/dist/cli/services/update-service.js +13 -6
  246. package/dist/cli/services/vpn-service.d.ts +28 -0
  247. package/dist/cli/services/vpn-service.js +46 -0
  248. package/dist/cli/services/web-service.d.ts +22 -0
  249. package/dist/cli/services/web-service.js +111 -0
  250. package/dist/cli/tui/app.d.ts +12 -4
  251. package/dist/cli/tui/app.js +38 -9
  252. package/dist/cli/tui/dialogs/path-listing.d.ts +43 -0
  253. package/dist/cli/tui/dialogs/path-listing.js +127 -0
  254. package/dist/cli/tui/dialogs/path-picker.d.ts +67 -0
  255. package/dist/cli/tui/dialogs/path-picker.js +423 -0
  256. package/dist/cli/tui/dialogs/text-screen.d.ts +6 -0
  257. package/dist/cli/tui/dialogs/text-screen.js +10 -3
  258. package/dist/cli/tui/frame.d.ts +7 -10
  259. package/dist/cli/tui/frame.js +19 -10
  260. package/dist/cli/tui/index.d.ts +4 -3
  261. package/dist/cli/tui/index.js +2 -1
  262. package/dist/cli/tui/list/list-screen.d.ts +28 -2
  263. package/dist/cli/tui/list/list-screen.js +130 -66
  264. package/dist/cli/tui/list/list-types.d.ts +10 -4
  265. package/dist/cli/tui/nav.d.ts +29 -0
  266. package/dist/cli/tui/nav.js +67 -0
  267. package/dist/cli/tui/terminal.d.ts +7 -0
  268. package/dist/cli/tui/terminal.js +30 -10
  269. package/dist/cli/validate.d.ts +1 -1
  270. package/dist/cli/validate.js +3 -3
  271. package/dist/cli/version.d.ts +2 -0
  272. package/dist/cli/version.js +11 -0
  273. package/dist/core/config/defaults.js +13 -1
  274. package/dist/core/config/loader.js +12 -2
  275. package/dist/core/local-config/overrides.js +1 -0
  276. package/dist/core/prompt.d.ts +19 -0
  277. package/dist/core/prompt.js +43 -3
  278. package/dist/core/schema/common.d.ts +6 -0
  279. package/dist/core/schema/common.js +8 -0
  280. package/dist/core/schema/config.d.ts +36 -0
  281. package/dist/core/schema/config.js +26 -2
  282. package/dist/core/schema/harness.d.ts +2 -0
  283. package/dist/core/schema/harness.js +13 -2
  284. package/dist/core/schema/index.d.ts +3 -1
  285. package/dist/core/schema/index.js +3 -1
  286. package/dist/core/schema/profile.d.ts +1 -0
  287. package/dist/core/schema/profile.js +3 -0
  288. package/dist/core/schema/redact.d.ts +13 -0
  289. package/dist/core/schema/redact.js +75 -0
  290. package/dist/core/schema/sandbox.d.ts +6 -0
  291. package/dist/core/schema/sandbox.js +21 -3
  292. package/dist/core/schema/vpn.d.ts +18 -0
  293. package/dist/core/schema/vpn.js +22 -0
  294. package/dist/core/schema/web.d.ts +6 -0
  295. package/dist/core/schema/web.js +14 -0
  296. package/dist/core/types.d.ts +44 -0
  297. package/dist/core/util/fs.d.ts +2 -0
  298. package/dist/core/util/fs.js +9 -0
  299. package/dist/core/util/index.d.ts +1 -1
  300. package/dist/core/util/index.js +1 -1
  301. package/dist/guest/agents/agent-files.d.ts +54 -0
  302. package/dist/guest/agents/agent-files.js +67 -0
  303. package/dist/guest/agents/agent-installer.js +2 -9
  304. package/dist/guest/agents/local-state.d.ts +14 -0
  305. package/dist/guest/agents/local-state.js +218 -0
  306. package/dist/guest/agents/sbx-agent.d.ts +2 -0
  307. package/dist/guest/agents/sbx-agent.js +35 -0
  308. package/dist/guest/boot/boot.d.ts +4 -0
  309. package/dist/guest/boot/boot.js +51 -11
  310. package/dist/guest/daemon/daemon.js +8 -1
  311. package/dist/guest/daemon/exec.js +2 -1
  312. package/dist/guest/daemon/idle-shutdown.js +2 -0
  313. package/dist/guest/daemon/sessions.d.ts +5 -0
  314. package/dist/guest/daemon/sessions.js +20 -3
  315. package/dist/guest/entries/agent.d.ts +1 -0
  316. package/dist/guest/entries/agent.js +10 -0
  317. package/dist/guest/entries/daemon.js +5 -0
  318. package/dist/guest/governor/decide.d.ts +61 -0
  319. package/dist/guest/governor/decide.js +182 -0
  320. package/dist/guest/governor/governor.d.ts +42 -0
  321. package/dist/guest/governor/governor.js +214 -0
  322. package/dist/guest/governor/index.d.ts +2 -0
  323. package/dist/guest/governor/index.js +2 -0
  324. package/dist/guest/runtime/csc.d.ts +2 -0
  325. package/dist/guest/runtime/csc.js +2 -0
  326. package/dist/guest/runtime/secrets.d.ts +12 -0
  327. package/dist/guest/runtime/secrets.js +63 -0
  328. package/dist/guest/sessions/viewer.js +3 -1
  329. package/dist/guest/setup/claude-profile.d.ts +2 -1
  330. package/dist/guest/setup/claude-profile.js +12 -1
  331. package/dist/guest/setup/environment.d.ts +6 -0
  332. package/dist/guest/setup/environment.js +56 -6
  333. package/dist/guest/setup/path-plan.d.ts +32 -0
  334. package/dist/guest/setup/path-plan.js +67 -0
  335. package/dist/guest/setup/shell-path.d.ts +1 -0
  336. package/dist/guest/setup/shell-path.js +22 -0
  337. package/dist/guest/toolchains/languages/python.js +1 -1
  338. package/dist/guest/toolchains/native/rust-extras.js +4 -2
  339. package/dist/guest/toolchains/runtimes.js +2 -2
  340. package/dist/guest/vpn/index.d.ts +1 -0
  341. package/dist/guest/vpn/index.js +1 -0
  342. package/dist/guest/vpn/openvpn.d.ts +9 -0
  343. package/dist/guest/vpn/openvpn.js +47 -0
  344. package/dist/guest/vpn/tunnel.d.ts +17 -0
  345. package/dist/guest/vpn/tunnel.js +78 -0
  346. package/dist/guest/vpn/vpn.d.ts +6 -0
  347. package/dist/guest/vpn/vpn.js +174 -0
  348. package/dist/guest/vpn/wireguard.d.ts +32 -0
  349. package/dist/guest/vpn/wireguard.js +132 -0
  350. package/dist/host/agent-commands/commands.d.ts +4 -0
  351. package/dist/host/agent-commands/commands.js +31 -7
  352. package/dist/host/audit/log.d.ts +1 -1
  353. package/dist/host/channel/attach.d.ts +6 -2
  354. package/dist/host/channel/attach.js +6 -3
  355. package/dist/host/channel/channel.d.ts +9 -0
  356. package/dist/host/channel/channel.js +30 -2
  357. package/dist/host/engines/engine.d.ts +12 -0
  358. package/dist/host/engines/engine.js +1 -0
  359. package/dist/host/engines/hcs/check.d.ts +25 -0
  360. package/dist/host/engines/hcs/check.js +95 -0
  361. package/dist/host/engines/hcs/documents.d.ts +44 -0
  362. package/dist/host/engines/hcs/documents.js +155 -0
  363. package/dist/host/engines/hcs/engine.d.ts +39 -0
  364. package/dist/host/engines/hcs/engine.js +171 -0
  365. package/dist/host/engines/hcs/helper.d.ts +43 -0
  366. package/dist/host/engines/hcs/helper.js +173 -0
  367. package/dist/host/engines/hcs/images.d.ts +37 -0
  368. package/dist/host/engines/hcs/images.js +152 -0
  369. package/dist/host/engines/index.d.ts +7 -0
  370. package/dist/host/engines/index.js +5 -0
  371. package/dist/host/engines/registry.d.ts +16 -0
  372. package/dist/host/engines/registry.js +30 -0
  373. package/dist/host/engines/types.d.ts +58 -0
  374. package/dist/host/engines/types.js +1 -0
  375. package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
  376. package/dist/host/engines/windows-sandbox/engine.js +63 -0
  377. package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
  378. package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
  379. package/dist/host/health/acl-read.d.ts +17 -0
  380. package/dist/host/health/acl-read.js +45 -0
  381. package/dist/host/health/config-backup.d.ts +11 -0
  382. package/dist/host/health/config-backup.js +73 -0
  383. package/dist/host/health/index.d.ts +6 -0
  384. package/dist/host/health/index.js +7 -0
  385. package/dist/host/health/install-state.d.ts +33 -0
  386. package/dist/host/health/install-state.js +110 -0
  387. package/dist/host/health/path-copies.d.ts +32 -0
  388. package/dist/host/health/path-copies.js +82 -0
  389. package/dist/host/health/stale.d.ts +45 -0
  390. package/dist/host/health/stale.js +120 -0
  391. package/dist/host/health/system.d.ts +37 -0
  392. package/dist/host/health/system.js +87 -0
  393. package/dist/host/install/copies.d.ts +13 -0
  394. package/dist/host/install/copies.js +63 -0
  395. package/dist/host/install/index.d.ts +1 -0
  396. package/dist/host/install/index.js +1 -0
  397. package/dist/host/launch/generate.d.ts +5 -1
  398. package/dist/host/launch/generate.js +73 -7
  399. package/dist/host/launch/index.d.ts +3 -1
  400. package/dist/host/launch/index.js +3 -1
  401. package/dist/host/launch/launch-plan.d.ts +13 -0
  402. package/dist/host/launch/launch-plan.js +26 -0
  403. package/dist/host/launch/mappings.js +2 -1
  404. package/dist/host/launch/risk-notes.d.ts +10 -0
  405. package/dist/host/launch/risk-notes.js +18 -0
  406. package/dist/host/launch/session-file.d.ts +2 -0
  407. package/dist/host/launch/session-file.js +11 -2
  408. package/dist/host/launch/stage.js +1 -1
  409. package/dist/host/launch/wsb-file.d.ts +28 -4
  410. package/dist/host/launch/wsb-file.js +61 -42
  411. package/dist/host/life/crash-report.d.ts +27 -1
  412. package/dist/host/life/crash-report.js +173 -7
  413. package/dist/host/life/host-memory.d.ts +40 -0
  414. package/dist/host/life/host-memory.js +137 -0
  415. package/dist/host/life/index.d.ts +2 -0
  416. package/dist/host/life/index.js +2 -0
  417. package/dist/host/life/stop-events.d.ts +2 -0
  418. package/dist/host/life/stop-events.js +20 -3
  419. package/dist/host/life/stop-warning.js +1 -1
  420. package/dist/host/life/watchdog.d.ts +54 -0
  421. package/dist/host/life/watchdog.js +108 -0
  422. package/dist/host/migrate/backup.js +3 -0
  423. package/dist/host/migrate/migrations/config-file.d.ts +2 -0
  424. package/dist/host/migrate/migrations/config-file.js +7 -0
  425. package/dist/host/migrate/migrations/follow-machine-storage.js +9 -1
  426. package/dist/host/migrate/migrations/pin-storage-root.d.ts +4 -0
  427. package/dist/host/migrate/migrations/pin-storage-root.js +46 -0
  428. package/dist/host/migrate/migrations/unpin-config-defaults.js +4 -1
  429. package/dist/host/migrate/registry.js +2 -1
  430. package/dist/host/native.d.ts +3 -2
  431. package/dist/host/native.js +22 -3
  432. package/dist/host/profile/accounts.d.ts +25 -1
  433. package/dist/host/profile/accounts.js +96 -13
  434. package/dist/host/profile/agent-accounts.d.ts +5 -1
  435. package/dist/host/profile/agent-accounts.js +35 -5
  436. package/dist/host/profile/claude-login.js +3 -2
  437. package/dist/host/profile/index.d.ts +2 -1
  438. package/dist/host/profile/index.js +1 -0
  439. package/dist/host/profile/plugin-share.d.ts +26 -0
  440. package/dist/host/profile/plugin-share.js +146 -0
  441. package/dist/host/projects/join.d.ts +7 -1
  442. package/dist/host/projects/join.js +21 -4
  443. package/dist/host/projects/registry.d.ts +16 -10
  444. package/dist/host/projects/registry.js +74 -6
  445. package/dist/host/sandbox/contained-deps.d.ts +2 -0
  446. package/dist/host/sandbox/contained-deps.js +17 -0
  447. package/dist/host/sandbox/index.d.ts +2 -0
  448. package/dist/host/sandbox/index.js +2 -0
  449. package/dist/host/sandbox/platform.d.ts +4 -0
  450. package/dist/host/sandbox/platform.js +23 -4
  451. package/dist/host/sandbox/tasklist.d.ts +13 -0
  452. package/dist/host/sandbox/tasklist.js +47 -0
  453. package/dist/host/secrets/index.d.ts +2 -0
  454. package/dist/host/secrets/index.js +2 -0
  455. package/dist/host/secrets/launch-secrets.d.ts +17 -0
  456. package/dist/host/secrets/launch-secrets.js +94 -0
  457. package/dist/host/secrets/secret-store.d.ts +25 -0
  458. package/dist/host/secrets/secret-store.js +89 -0
  459. package/dist/host/sharing/acl.d.ts +16 -2
  460. package/dist/host/sharing/acl.js +35 -10
  461. package/dist/host/sharing/current.js +8 -3
  462. package/dist/host/sharing/doctor.d.ts +2 -0
  463. package/dist/host/sharing/doctor.js +44 -0
  464. package/dist/host/sharing/group-access.d.ts +6 -0
  465. package/dist/host/sharing/group-access.js +24 -0
  466. package/dist/host/sharing/index.d.ts +2 -1
  467. package/dist/host/sharing/index.js +2 -1
  468. package/dist/host/sharing/lifecycle.d.ts +8 -2
  469. package/dist/host/sharing/lifecycle.js +16 -7
  470. package/dist/host/storage/cleanup.d.ts +2 -0
  471. package/dist/host/storage/cleanup.js +2 -1
  472. package/dist/host/storage/contained/check.d.ts +9 -0
  473. package/dist/host/storage/contained/check.js +37 -0
  474. package/dist/host/storage/contained/contained-storage.d.ts +66 -0
  475. package/dist/host/storage/contained/contained-storage.js +168 -0
  476. package/dist/host/storage/contained/disk-port.d.ts +43 -0
  477. package/dist/host/storage/contained/disk-port.js +122 -0
  478. package/dist/host/storage/contained/index.d.ts +9 -0
  479. package/dist/host/storage/contained/index.js +8 -0
  480. package/dist/host/storage/contained/layout.d.ts +28 -0
  481. package/dist/host/storage/contained/layout.js +45 -0
  482. package/dist/host/storage/contained/resolve.d.ts +4 -0
  483. package/dist/host/storage/contained/resolve.js +30 -0
  484. package/dist/host/storage/contained/setting.d.ts +1 -0
  485. package/dist/host/storage/contained/setting.js +5 -0
  486. package/dist/host/storage/contained/state.d.ts +89 -0
  487. package/dist/host/storage/contained/state.js +166 -0
  488. package/dist/host/storage/contained/transfer.d.ts +24 -0
  489. package/dist/host/storage/contained/transfer.js +121 -0
  490. package/dist/host/storage/history.d.ts +21 -0
  491. package/dist/host/storage/history.js +49 -0
  492. package/dist/host/storage/index.d.ts +6 -0
  493. package/dist/host/storage/index.js +6 -0
  494. package/dist/host/storage/move.d.ts +95 -0
  495. package/dist/host/storage/move.js +384 -0
  496. package/dist/host/storage/offer.d.ts +11 -0
  497. package/dist/host/storage/offer.js +36 -0
  498. package/dist/host/storage/providers/contained.d.ts +15 -0
  499. package/dist/host/storage/providers/contained.js +39 -0
  500. package/dist/host/storage/providers/folder.d.ts +12 -0
  501. package/dist/host/storage/providers/folder.js +20 -0
  502. package/dist/host/storage/providers/index.d.ts +4 -0
  503. package/dist/host/storage/providers/index.js +3 -0
  504. package/dist/host/storage/providers/registry.d.ts +9 -0
  505. package/dist/host/storage/providers/registry.js +14 -0
  506. package/dist/host/storage/providers/types.d.ts +33 -0
  507. package/dist/host/storage/providers/types.js +1 -0
  508. package/dist/host/storage/root.d.ts +18 -0
  509. package/dist/host/storage/root.js +77 -0
  510. package/dist/host/tools/conpty.js +3 -2
  511. package/dist/host/tools/windows-terminal.d.ts +2 -0
  512. package/dist/host/tools/windows-terminal.js +31 -12
  513. package/dist/host/update/index.d.ts +1 -1
  514. package/dist/host/update/index.js +1 -1
  515. package/dist/host/update/notice.d.ts +2 -0
  516. package/dist/host/update/notice.js +13 -1
  517. package/dist/host/update/update-state.d.ts +6 -0
  518. package/dist/host/update/update-state.js +2 -0
  519. package/dist/host/update/updater.d.ts +19 -0
  520. package/dist/host/update/updater.js +88 -12
  521. package/dist/host/vpn/index.d.ts +4 -0
  522. package/dist/host/vpn/index.js +4 -0
  523. package/dist/host/vpn/login.d.ts +24 -0
  524. package/dist/host/vpn/login.js +79 -0
  525. package/dist/host/vpn/nordvpn.d.ts +21 -0
  526. package/dist/host/vpn/nordvpn.js +77 -0
  527. package/dist/host/vpn/prepare.d.ts +19 -0
  528. package/dist/host/vpn/prepare.js +138 -0
  529. package/dist/host/vpn/status.d.ts +12 -0
  530. package/dist/host/vpn/status.js +53 -0
  531. package/dist/host/web/auth.d.ts +38 -0
  532. package/dist/host/web/auth.js +96 -0
  533. package/dist/host/web/backend.d.ts +14 -0
  534. package/dist/host/web/backend.js +1 -0
  535. package/dist/host/web/bridge.d.ts +27 -0
  536. package/dist/host/web/bridge.js +144 -0
  537. package/dist/host/web/browser.d.ts +3 -0
  538. package/dist/host/web/browser.js +23 -0
  539. package/dist/host/web/control.d.ts +17 -0
  540. package/dist/host/web/control.js +67 -0
  541. package/dist/host/web/index.d.ts +10 -0
  542. package/dist/host/web/index.js +9 -0
  543. package/dist/host/web/rpc.d.ts +24 -0
  544. package/dist/host/web/rpc.js +149 -0
  545. package/dist/host/web/runner.d.ts +16 -0
  546. package/dist/host/web/runner.js +44 -0
  547. package/dist/host/web/server.d.ts +47 -0
  548. package/dist/host/web/server.js +238 -0
  549. package/dist/host/web/state.d.ts +20 -0
  550. package/dist/host/web/state.js +41 -0
  551. package/dist/host/web/static-files.d.ts +13 -0
  552. package/dist/host/web/static-files.js +57 -0
  553. package/dist/runtime/agent.js +27675 -0
  554. package/dist/runtime/daemon.js +1950 -1122
  555. package/dist/runtime/db.js +302 -111
  556. package/dist/runtime/main.js +1560 -275
  557. package/dist/runtime/netproxy.js +168 -8
  558. package/dist/runtime/view.js +186 -13
  559. package/dist/selftest/accounts.test.js +40 -0
  560. package/dist/selftest/agent-paths.test.d.ts +2 -0
  561. package/dist/selftest/agent-paths.test.js +125 -0
  562. package/dist/selftest/app.test.d.ts +2 -0
  563. package/dist/selftest/app.test.js +324 -0
  564. package/dist/selftest/channel.test.js +18 -0
  565. package/dist/selftest/cli.test.js +35 -4
  566. package/dist/selftest/config.test.js +59 -0
  567. package/dist/selftest/contained.test.d.ts +2 -0
  568. package/dist/selftest/contained.test.js +544 -0
  569. package/dist/selftest/credentials.test.d.ts +2 -0
  570. package/dist/selftest/credentials.test.js +198 -0
  571. package/dist/selftest/engine.test.d.ts +2 -0
  572. package/dist/selftest/engine.test.js +127 -0
  573. package/dist/selftest/generate.test.js +1 -1
  574. package/dist/selftest/hcs.test.d.ts +2 -0
  575. package/dist/selftest/hcs.test.js +482 -0
  576. package/dist/selftest/health.test.d.ts +2 -0
  577. package/dist/selftest/health.test.js +470 -0
  578. package/dist/selftest/heavy-load.test.d.ts +2 -0
  579. package/dist/selftest/heavy-load.test.js +329 -0
  580. package/dist/selftest/host-sim.test.js +2 -0
  581. package/dist/selftest/index.js +31 -0
  582. package/dist/selftest/layout.test.js +14 -0
  583. package/dist/selftest/menu-perf.test.d.ts +2 -0
  584. package/dist/selftest/menu-perf.test.js +248 -0
  585. package/dist/selftest/menu-screens.d.ts +7 -0
  586. package/dist/selftest/menu-screens.js +68 -17
  587. package/dist/selftest/menu.test.js +603 -22
  588. package/dist/selftest/migrate.test.js +1 -1
  589. package/dist/selftest/personalization.test.js +3 -1
  590. package/dist/selftest/projects.test.js +39 -1
  591. package/dist/selftest/shared-use.test.js +64 -2
  592. package/dist/selftest/sharing.test.js +50 -1
  593. package/dist/selftest/storage.test.d.ts +2 -0
  594. package/dist/selftest/storage.test.js +363 -0
  595. package/dist/selftest/support/engine-cases.d.ts +8 -0
  596. package/dist/selftest/support/engine-cases.js +65 -0
  597. package/dist/selftest/support/engine-golden.d.ts +3 -0
  598. package/dist/selftest/support/engine-golden.js +66 -0
  599. package/dist/selftest/support/fixtures.d.ts +20 -0
  600. package/dist/selftest/support/hcs-probes.d.ts +17 -0
  601. package/dist/selftest/support/hcs-probes.js +41 -0
  602. package/dist/selftest/support/releases.js +1 -1
  603. package/dist/selftest/toolchains.test.js +21 -0
  604. package/dist/selftest/update-service.test.js +87 -3
  605. package/dist/selftest/vpn.test.d.ts +2 -0
  606. package/dist/selftest/vpn.test.js +412 -0
  607. package/dist/selftest/web.test.d.ts +2 -0
  608. package/dist/selftest/web.test.js +402 -0
  609. package/dist/shared/apps/catalogue.js +31 -0
  610. package/dist/shared/channel/index.d.ts +1 -0
  611. package/dist/shared/channel/index.js +1 -0
  612. package/dist/shared/channel/run-dir.d.ts +9 -1
  613. package/dist/shared/channel/run-dir.js +18 -1
  614. package/dist/shared/channel/schema.d.ts +53 -0
  615. package/dist/shared/channel/schema.js +38 -0
  616. package/dist/shared/channel/secrets.d.ts +29 -0
  617. package/dist/shared/channel/secrets.js +50 -0
  618. package/dist/shared/memory/index.d.ts +1 -0
  619. package/dist/shared/memory/index.js +1 -0
  620. package/dist/shared/memory/policy.d.ts +33 -0
  621. package/dist/shared/memory/policy.js +55 -0
  622. package/dist/shared/pty/output-filter.d.ts +14 -1
  623. package/dist/shared/pty/output-filter.js +22 -4
  624. package/dist/shared/pty/terminal.d.ts +4 -1
  625. package/dist/shared/pty/terminal.js +4 -2
  626. package/dist/shared/system.d.ts +1 -0
  627. package/dist/shared/system.js +1 -0
  628. package/dist/shared/vpn/download.d.ts +29 -0
  629. package/dist/shared/vpn/download.js +30 -0
  630. package/dist/shared/vpn/kill-switch.d.ts +18 -0
  631. package/dist/shared/vpn/kill-switch.js +81 -0
  632. package/dist/shared/vpn/ovpn.d.ts +23 -0
  633. package/dist/shared/vpn/ovpn.js +244 -0
  634. package/dist/shared/vpn/wireguard.d.ts +51 -0
  635. package/dist/shared/vpn/wireguard.js +227 -0
  636. package/dist/shared/web/index.d.ts +1 -0
  637. package/dist/shared/web/index.js +1 -0
  638. package/dist/shared/web/protocol.d.ts +61 -0
  639. package/dist/shared/web/protocol.js +35 -0
  640. package/dist/sync/sync-cycle.js +9 -5
  641. package/dist/sync/sync-state.d.ts +1 -0
  642. package/dist/sync/sync-state.js +1 -0
  643. package/dist/sync/watcher.d.ts +13 -0
  644. package/dist/sync/watcher.js +102 -3
  645. package/dist/web/index.html +14 -0
  646. package/dist/web/main-NRRS5O6Z.js +157 -0
  647. package/dist/web/main-T5DMCHYV.css +1 -0
  648. package/native/csharp/FolderSecurity.cs +29 -0
  649. package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
  650. package/native/csharp/HcsHost/Guard.cs +100 -0
  651. package/native/csharp/HcsHost/Hcs.cs +256 -0
  652. package/native/csharp/HcsHost/Json.cs +78 -0
  653. package/native/csharp/HcsHost/Program.cs +185 -0
  654. package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
  655. package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
  656. package/native/csharp/HostTools/MemoryStatus.cs +107 -0
  657. package/native/csharp/HostTools/Program.cs +58 -17
  658. package/native/scripts/check-contained.ps1 +28 -0
  659. package/native/scripts/contained-common.ps1 +241 -0
  660. package/native/scripts/dismount-contained.ps1 +66 -0
  661. package/native/scripts/memory-status.ps1 +34 -0
  662. package/native/scripts/mount-contained.ps1 +139 -0
  663. package/native/scripts/protect-data.ps1 +29 -0
  664. package/native/scripts/read-folder-sddl.ps1 +10 -0
  665. package/native/scripts/run-elevated.ps1 +17 -4
  666. package/native/scripts/set-folder-access.ps1 +49 -7
  667. package/native/scripts/stop-events.ps1 +23 -8
  668. package/node_modules/ws/LICENSE +20 -0
  669. package/node_modules/ws/README.md +548 -0
  670. package/node_modules/ws/browser.js +8 -0
  671. package/node_modules/ws/index.js +22 -0
  672. package/node_modules/ws/lib/buffer-util.js +131 -0
  673. package/node_modules/ws/lib/constants.js +19 -0
  674. package/node_modules/ws/lib/event-target.js +292 -0
  675. package/node_modules/ws/lib/extension.js +203 -0
  676. package/node_modules/ws/lib/limiter.js +55 -0
  677. package/node_modules/ws/lib/permessage-deflate.js +530 -0
  678. package/node_modules/ws/lib/receiver.js +743 -0
  679. package/node_modules/ws/lib/sender.js +607 -0
  680. package/node_modules/ws/lib/stream.js +161 -0
  681. package/node_modules/ws/lib/subprotocol.js +62 -0
  682. package/node_modules/ws/lib/validation.js +152 -0
  683. package/node_modules/ws/lib/websocket-server.js +562 -0
  684. package/node_modules/ws/lib/websocket.js +1421 -0
  685. package/node_modules/ws/package.json +74 -0
  686. package/node_modules/ws/wrapper.mjs +21 -0
  687. package/package.json +22 -5
  688. package/sandbox/csharp/EnvBroadcast.cs +33 -0
  689. package/sandbox/csharp/MemGov.cs +398 -0
  690. package/sandbox/csharp/PathSync.cs +90 -0
  691. package/sandbox/csharp/PtyHost.cs +111 -5
  692. package/sandbox/scripts/install-shell-path.ps1 +73 -0
  693. package/sandbox/scripts/set-machine-environment.ps1 +37 -4
  694. package/schemas/config.schema.json +136 -7
  695. package/schemas/sandbox-config.schema.json +17 -4
  696. package/dist/cli/commands/repair/checks.d.ts +0 -2
  697. package/dist/cli/commands/repair/checks.js +0 -246
  698. package/dist/cli/commands/sessions/control.d.ts +0 -4
  699. package/dist/cli/commands/sessions/control.js +0 -66
  700. package/dist/cli/commands/sessions/list.d.ts +0 -2
  701. package/dist/cli/commands/sessions/list.js +0 -45
  702. package/dist/cli/commands/sessions/status.d.ts +0 -2
  703. package/dist/cli/commands/sessions/status.js +0 -93
  704. package/dist/cli/commands/sessions/window.d.ts +0 -3
  705. package/dist/cli/commands/sessions/window.js +0 -18
  706. package/dist/cli/menu/pages/start-page.d.ts +0 -43
  707. package/dist/cli/menu/pages/start-page.js +0 -192
  708. package/dist/cli/tui/tab-bar.d.ts +0 -9
  709. package/dist/cli/tui/tab-bar.js +0 -33
@@ -0,0 +1,120 @@
1
+ // What a closed or crashed sandbox leaves behind, and how to tell it from what is in use: records of sandboxes that are
2
+ // gone, run files, old launch folders, background watchers with nothing to watch. These only look; the repair checks
3
+ // remove through the safe helpers. Everything takes its folders as arguments, so tests use temp folders.
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { z } from 'zod';
7
+ import { dirExists, isLink } from '../../core/util/index.js';
8
+ import { RunDir } from '../../shared/channel/index.js';
9
+ const DAY = 24 * 60 * 60 * 1000;
10
+ const SANDBOX_IMAGES = ['windowssandboxclient.exe', 'windowssandboxremotesession.exe', 'windowssandbox.exe'];
11
+ /** A watcher this old, with its log quiet and no sandbox, is left over (a finishing one is done within minutes). */
12
+ export const WATCHER_MIN_AGE_MS = 10 * 60 * 1000;
13
+ export const WATCHER_LOG_QUIET_MS = 5 * 60 * 1000;
14
+ /** Windows sessions that have a sandbox running (empty: none runs). */
15
+ export function sandboxSessions(rows) {
16
+ const found = rows.filter((r) => SANDBOX_IMAGES.includes(r.image.toLowerCase()));
17
+ return [...new Set(found.map((r) => r.session))];
18
+ }
19
+ /** Sharing records whose Windows session has no sandbox running (nothing else removes them after a crash). */
20
+ export function staleActiveRecords(records, rows) {
21
+ const sessions = sandboxSessions(rows);
22
+ return records.filter((r) => !sessions.includes(r.windowsSession));
23
+ }
24
+ /** What is left in <data>\run by a sandbox that is no longer running. */
25
+ export function runStateProblems(dataPath) {
26
+ const run = new RunDir(dataPath);
27
+ const sessions = run.listSessions().filter((s) => s.phase === 'running' || s.phase === 'starting').length;
28
+ const found = run.scanRequests();
29
+ const requests = found.valid.length + found.invalid.length;
30
+ const phase = run.readSandboxStatus()?.phase;
31
+ const unfinishedBoot = phase && phase !== 'ready' ? phase : null;
32
+ return { sessions, requests, unfinishedBoot, any: sessions > 0 || requests > 0 || unfinishedBoot !== null };
33
+ }
34
+ /** Launch folders under <storage>\launches that nothing has touched for `days` days (each is a finished start). */
35
+ export function staleLaunchFolders(storageRoot, days, now, keep = []) {
36
+ const dir = path.join(storageRoot, 'launches');
37
+ if (!dirExists(dir) || isLink(dir))
38
+ return [];
39
+ const found = [];
40
+ for (const name of fs.readdirSync(dir)) {
41
+ if (keep.includes(name))
42
+ continue;
43
+ const full = path.join(dir, name);
44
+ try {
45
+ const age = now - fs.lstatSync(full).mtimeMs;
46
+ if (age > days * DAY)
47
+ found.push({ path: full, ageDays: Math.floor(age / DAY) });
48
+ }
49
+ catch {
50
+ // gone while we looked
51
+ }
52
+ }
53
+ return found;
54
+ }
55
+ const PidSchema = z.coerce.number().int().positive();
56
+ /** The history-sync watcher records in <storage>\run (watcher-<data set>.pid) with the age of each and of its log. */
57
+ export function watcherRecords(storageRoot, now) {
58
+ const dir = path.join(storageRoot, 'run');
59
+ if (!dirExists(dir) || isLink(dir))
60
+ return [];
61
+ const age = (p) => {
62
+ try {
63
+ return now - fs.statSync(p).mtimeMs;
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ };
69
+ return fs
70
+ .readdirSync(dir)
71
+ .map((name) => ({ name, m: /^watcher-(.+)\.pid$/i.exec(name) }))
72
+ .flatMap(({ name, m }) => {
73
+ if (!m)
74
+ return [];
75
+ const file = path.join(dir, name);
76
+ let pid = null;
77
+ try {
78
+ const parsed = PidSchema.safeParse(fs.readFileSync(file, 'utf8').trim());
79
+ pid = parsed.success ? parsed.data : null;
80
+ }
81
+ catch {
82
+ return [];
83
+ }
84
+ return [
85
+ {
86
+ file,
87
+ pid,
88
+ ageMs: age(file) ?? 0,
89
+ logAgeMs: age(path.join(storageRoot, 'logs', 'host-sync-' + m[1] + '.log')),
90
+ },
91
+ ];
92
+ });
93
+ }
94
+ /**
95
+ * Watchers that run with no sandbox to watch: the process is alive and is a Node program (a recycled pid is somebody
96
+ * else's), no sandbox runs, and neither its record nor its log has changed for a while (a finishing watcher is spared).
97
+ */
98
+ export function orphanWatchers(infos, o) {
99
+ if (o.running)
100
+ return [];
101
+ return infos.filter((w) => w.pid !== null &&
102
+ o.alive(w.pid) &&
103
+ o.image(w.pid)?.toLowerCase() === 'node.exe' &&
104
+ w.ageMs > WATCHER_MIN_AGE_MS &&
105
+ (w.logAgeMs === null || w.logAgeMs > WATCHER_LOG_QUIET_MS));
106
+ }
107
+ /** null when a small file can be created in the folder, else the reason (the file is removed again). */
108
+ export function writeProblem(dir) {
109
+ const probe = path.join(dir, '.write-test-' + process.pid);
110
+ try {
111
+ fs.writeFileSync(probe, '');
112
+ return null;
113
+ }
114
+ catch (e) {
115
+ return e.code ?? String(e);
116
+ }
117
+ finally {
118
+ fs.rmSync(probe, { force: true });
119
+ }
120
+ }
@@ -0,0 +1,37 @@
1
+ import { type TaskRow } from '../sharing/index.js';
2
+ /** The mandatory-level SID of an elevated (admin) token. */
3
+ export declare const HIGH_INTEGRITY_SID = "S-1-16-12288";
4
+ export { SHARING_GROUP } from './acl-read.js';
5
+ export interface SystemProbe {
6
+ processes(): TaskRow[];
7
+ pidAlive(pid: number): boolean;
8
+ /** Ends one process (the caller has checked it is the right one). */
9
+ stop(pid: number): void;
10
+ /** The unexpanded PATH of this user or of the PC, or null when it cannot be read. */
11
+ registryPath(scope: 'user' | 'machine'): string | null;
12
+ /** Is the automatic-update task there? null when it cannot be asked. */
13
+ updateTaskExists(): boolean | null;
14
+ /** `icacls <folder>` output, or null. */
15
+ icacls(dir: string): string | null;
16
+ /** The accounts in the sharing group, or null when it cannot be read (no such group included). */
17
+ groupMembers(): string[] | null;
18
+ /** Is this SID in the token of this very process? null when whoami fails. */
19
+ tokenHasGroup(sid: string): boolean | null;
20
+ /** Does an HTTPS request to the address answer within `ms`? */
21
+ reachable(url: string, ms: number): Promise<boolean>;
22
+ }
23
+ /** The PATH value in `reg query ... /v Path` output, or null. */
24
+ export declare function parseRegPath(text: string): string | null;
25
+ /** The accounts listed by `net localgroup <name>`: the lines between the dashes and the closing sentence. */
26
+ export declare function parseGroupMembers(text: string): string[] | null;
27
+ export declare class WindowsProbe implements SystemProbe {
28
+ processes(): TaskRow[];
29
+ pidAlive(pid: number): boolean;
30
+ stop(pid: number): void;
31
+ registryPath(scope: 'user' | 'machine'): string | null;
32
+ updateTaskExists(): boolean | null;
33
+ icacls(dir: string): string | null;
34
+ groupMembers(): string[] | null;
35
+ tokenHasGroup(sid: string): boolean | null;
36
+ reachable(url: string, ms: number): Promise<boolean>;
37
+ }
@@ -0,0 +1,87 @@
1
+ // What the health checks ask Windows (the processes, your PATH, the update task, folder permissions, the network). One
2
+ // interface so tests give their own answers on temp folders; the real one only reads, apart from stop().
3
+ import { spawnSync } from 'node:child_process';
4
+ import { SYSTEM, system32 } from '../../shared/system.js';
5
+ import { refuseInSelfTest } from '../test-guard.js';
6
+ import { listProcesses } from '../sharing/index.js';
7
+ import { SHARING_GROUP } from './acl-read.js';
8
+ const HELPER_TIMEOUT_MS = 15000;
9
+ const USER_ENVIRONMENT = 'HKCU\\Environment';
10
+ const MACHINE_ENVIRONMENT = 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment';
11
+ /** The mandatory-level SID of an elevated (admin) token. */
12
+ export const HIGH_INTEGRITY_SID = 'S-1-16-12288';
13
+ export { SHARING_GROUP } from './acl-read.js';
14
+ /** The PATH value in `reg query ... /v Path` output, or null. */
15
+ export function parseRegPath(text) {
16
+ const m = /^\s+Path\s+REG_(?:EXPAND_)?SZ\s+(.*)$/im.exec(text);
17
+ return m ? m[1].trim() : null;
18
+ }
19
+ /** The accounts listed by `net localgroup <name>`: the lines between the dashes and the closing sentence. */
20
+ export function parseGroupMembers(text) {
21
+ const lines = text.split(/\r?\n/);
22
+ const start = lines.findIndex((l) => /^-{5,}\s*$/.test(l));
23
+ if (start < 0)
24
+ return null;
25
+ const rest = lines.slice(start + 1);
26
+ const end = rest.findIndex((l) => l.trim() === '' || /^\S.*\.$/.test(l.trim()));
27
+ return rest
28
+ .slice(0, end < 0 ? rest.length : end)
29
+ .map((l) => l.trim())
30
+ .filter(Boolean);
31
+ }
32
+ function run(exe, args) {
33
+ const r = spawnSync(exe, args, { encoding: 'utf8', windowsHide: true, timeout: HELPER_TIMEOUT_MS });
34
+ return { out: (r.stdout ?? '') + (r.stderr ?? ''), status: r.error ? null : r.status };
35
+ }
36
+ export class WindowsProbe {
37
+ processes() {
38
+ return listProcesses();
39
+ }
40
+ pidAlive(pid) {
41
+ if (!Number.isInteger(pid) || pid <= 0)
42
+ return false;
43
+ try {
44
+ process.kill(pid, 0);
45
+ return true;
46
+ }
47
+ catch (e) {
48
+ return e.code === 'EPERM';
49
+ }
50
+ }
51
+ stop(pid) {
52
+ refuseInSelfTest('stop programs');
53
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
54
+ throw new Error('Not a process to stop: ' + pid);
55
+ process.kill(pid);
56
+ }
57
+ registryPath(scope) {
58
+ const r = run(SYSTEM.reg(), ['query', scope === 'user' ? USER_ENVIRONMENT : MACHINE_ENVIRONMENT, '/v', 'Path']);
59
+ return r.status === 0 ? parseRegPath(r.out) : null;
60
+ }
61
+ updateTaskExists() {
62
+ const r = run(system32('schtasks.exe'), ['/Query', '/TN', '\\WindowsDevelopmentSandbox\\Update']);
63
+ return r.status === null ? null : r.status === 0;
64
+ }
65
+ icacls(dir) {
66
+ const r = run(SYSTEM.icacls(), [dir]);
67
+ return r.status === 0 ? r.out : null;
68
+ }
69
+ groupMembers() {
70
+ const r = run(system32('net.exe'), ['localgroup', SHARING_GROUP]);
71
+ return r.status === 0 ? parseGroupMembers(r.out) : null;
72
+ }
73
+ tokenHasGroup(sid) {
74
+ const r = run(SYSTEM.whoami(), ['/groups', '/fo', 'csv', '/nh']);
75
+ return r.status === 0 ? r.out.includes('"' + sid + '"') : null;
76
+ }
77
+ async reachable(url, ms) {
78
+ try {
79
+ const response = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(ms) });
80
+ return response.status < 500;
81
+ }
82
+ catch {
83
+ // Any failure (DNS, proxy, timeout) means "not reachable"; the caller words what to do.
84
+ return false;
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,13 @@
1
+ import { InstallLayout } from './layout.js';
2
+ /** The install for everyone (%ProgramFiles%\WindowsDevelopmentSandbox), or null. */
3
+ export declare function machineInstall(env?: NodeJS.ProcessEnv): InstallLayout | null;
4
+ /** The install for just this user (%LOCALAPPDATA%\WindowsDevelopmentSandbox), or null. */
5
+ export declare function userInstall(env?: NodeJS.ProcessEnv): InstallLayout | null;
6
+ /** The installs that exist, the one for everyone first (it comes first on the PATH too). */
7
+ export declare function managedInstalls(env?: NodeJS.ProcessEnv): InstallLayout[];
8
+ /** Where this copy runs from, for `--version`: "all users, <folder>", "just you, <folder>", "npm copy, <folder>". */
9
+ export declare function describeCopy(packageRoot: string): string;
10
+ /** The line to print when this copy is not a managed install but one exists (it is hidden by this one), else null. */
11
+ export declare function hiddenInstallLine(packageRoot: string, env?: NodeJS.ProcessEnv): string | null;
12
+ /** hiddenInstallLine, but once per version (null afterwards). `storageRoot` holds the note that it was shown. */
13
+ export declare function takeHiddenInstallNotice(storageRoot: string, packageRoot: string, version: string, env?: NodeJS.ProcessEnv): string | null;
@@ -0,0 +1,63 @@
1
+ // Which managed installs exist on this PC, and what a copy that runs from somewhere else should say about them. A
2
+ // managed install (<ProgramFiles or %LOCALAPPDATA%>\WindowsDevelopmentSandbox) is found from any copy of the program,
3
+ // so an npm copy or a checkout still sees the machine install that shares sandboxes with other users.
4
+ import path from 'node:path';
5
+ import { z } from 'zod';
6
+ import { fileExists } from '../../core/util/index.js';
7
+ import { JsonFile } from '../../shared/io/index.js';
8
+ import { InstallLayout } from './layout.js';
9
+ const FOLDER = 'WindowsDevelopmentSandbox';
10
+ function installAt(base, scope) {
11
+ if (!base || !path.isAbsolute(base))
12
+ return null;
13
+ const root = path.join(base, FOLDER);
14
+ if (!fileExists(path.join(root, 'active-version')) && !fileExists(path.join(root, 'install.json')))
15
+ return null;
16
+ return InstallLayout.at(root, scope);
17
+ }
18
+ /** The install for everyone (%ProgramFiles%\WindowsDevelopmentSandbox), or null. */
19
+ export function machineInstall(env = process.env) {
20
+ return installAt(env.ProgramFiles, 'machine');
21
+ }
22
+ /** The install for just this user (%LOCALAPPDATA%\WindowsDevelopmentSandbox), or null. */
23
+ export function userInstall(env = process.env) {
24
+ return installAt(env.LOCALAPPDATA, 'user');
25
+ }
26
+ /** The installs that exist, the one for everyone first (it comes first on the PATH too). */
27
+ export function managedInstalls(env = process.env) {
28
+ return [machineInstall(env), userInstall(env)].filter((l) => l !== null);
29
+ }
30
+ /** Where this copy runs from, for `--version`: "all users, <folder>", "just you, <folder>", "npm copy, <folder>". */
31
+ export function describeCopy(packageRoot) {
32
+ const layout = InstallLayout.detect(packageRoot);
33
+ if (layout)
34
+ return (layout.scope === 'machine' ? 'all users, ' : 'just you, ') + layout.root;
35
+ const resolved = path.resolve(packageRoot);
36
+ const npm = path.basename(path.dirname(resolved)).toLowerCase() === 'node_modules';
37
+ return (npm ? 'npm copy, ' : 'from ') + resolved;
38
+ }
39
+ /** The line to print when this copy is not a managed install but one exists (it is hidden by this one), else null. */
40
+ export function hiddenInstallLine(packageRoot, env = process.env) {
41
+ if (InstallLayout.detect(packageRoot))
42
+ return null;
43
+ const installed = managedInstalls(env)[0];
44
+ if (!installed)
45
+ return null;
46
+ return ('Running the copy in ' +
47
+ path.resolve(packageRoot) +
48
+ '; the installed one in ' +
49
+ installed.root +
50
+ ' is hidden. sandbox doctor explains.');
51
+ }
52
+ const NoticeSchema = z.object({ version: z.string() });
53
+ /** hiddenInstallLine, but once per version (null afterwards). `storageRoot` holds the note that it was shown. */
54
+ export function takeHiddenInstallNotice(storageRoot, packageRoot, version, env = process.env) {
55
+ const line = hiddenInstallLine(packageRoot, env);
56
+ if (!line)
57
+ return null;
58
+ const file = new JsonFile(NoticeSchema, path.join(storageRoot, 'copy-notice.json'));
59
+ if (file.read()?.version === version)
60
+ return null;
61
+ file.write({ version });
62
+ return line;
63
+ }
@@ -2,3 +2,4 @@ export { type InstallScope, InstallLayout, compareVersions, VERSION_PATTERN, NOD
2
2
  export { shimText, readBins, writeShims } from './shims.js';
3
3
  export { InstallRecordFile, InstallRecordSchema, type InstallRecord } from './install-record.js';
4
4
  export { UpdateTask } from './scheduled-task.js';
5
+ export { machineInstall, userInstall, managedInstalls, describeCopy, hiddenInstallLine, takeHiddenInstallNotice, } from './copies.js';
@@ -2,3 +2,4 @@ export { InstallLayout, compareVersions, VERSION_PATTERN, NODE_PATTERN } from '.
2
2
  export { shimText, readBins, writeShims } from './shims.js';
3
3
  export { InstallRecordFile, InstallRecordSchema } from './install-record.js';
4
4
  export { UpdateTask } from './scheduled-task.js';
5
+ export { machineInstall, userInstall, managedInstalls, describeCopy, hiddenInstallLine, takeHiddenInstallNotice, } from './copies.js';
@@ -1,4 +1,8 @@
1
1
  import type { GenerateOptions, Generated } from '../../core/types.js';
2
- export declare function generateSandbox(given: GenerateOptions): Generated & {
2
+ import { type EnginePlan, type SandboxEngine } from '../engines/index.js';
3
+ export declare function generateSandbox(given: GenerateOptions,
4
+ /** The engine launch.ts opened (hcs needs a look at this PC first); Windows Sandbox when left out. */
5
+ opened?: SandboxEngine): Generated & {
3
6
  personalization: string;
7
+ enginePlan: EnginePlan;
4
8
  };
@@ -3,19 +3,37 @@
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
5
  import crypto from 'node:crypto';
6
+ import os from 'node:os';
6
7
  import { widenForProjects } from '../../core/local-config/index.js';
7
8
  import { dirExists, ensureDir, fail, writeJson } from '../../core/util/index.js';
9
+ import { engineFor } from '../engines/index.js';
8
10
  import { capturePersonalization, stageClaudeProfile } from '../profile/index.js';
11
+ import { clearSecrets, writeSecrets } from '../secrets/index.js';
12
+ import { folderAttachment } from '../storage/providers/index.js';
9
13
  import { assertTestWritable } from '../test-guard.js';
14
+ import { writeLoadSettings } from '../life/watchdog.js';
15
+ import { loadProfileOf } from './risk-notes.js';
10
16
  import { planBootProjects } from './boot-projects.js';
11
17
  import { planDatabases } from './database-plan.js';
12
18
  import { collectMappings } from './mappings.js';
13
19
  import { guestSession, logonEnv } from './session-file.js';
14
20
  import { copyRuntime, stageGitIdentity, stageHooks } from './stage.js';
15
21
  import { decideProjectToolchains } from './toolchains.js';
16
- import { buildWsb, resolveMemoryMb } from './wsb-file.js';
22
+ import { buildLaunchPlan } from './launch-plan.js';
23
+ import { decideMemory, GUEST, memoryNote, resolveMemoryMb } from './wsb-file.js';
17
24
  const NO_PROFILE = { hostDir: null, staged: [], skipped: [], credentials: false, secretsRemoved: [] };
18
- export function generateSandbox(given) {
25
+ /** Moves the staged copy of this PC's Claude login out of the launch folder; its text goes in the one-shot file. */
26
+ function takeStagedCredentials(launchPath) {
27
+ const file = path.join(launchPath, 'claude-profile', '.credentials.json');
28
+ if (!fs.existsSync(file))
29
+ return undefined;
30
+ const text = fs.readFileSync(file, 'utf8');
31
+ fs.rmSync(file, { force: true });
32
+ return text;
33
+ }
34
+ export function generateSandbox(given,
35
+ /** The engine launch.ts opened (hcs needs a look at this PC first); Windows Sandbox when left out. */
36
+ opened) {
19
37
  // Several projects at boot: the sandbox also gets what the others want and you allowed (core/local-config).
20
38
  const others = given.bootWants?.projects ?? [];
21
39
  const boot = planBootProjects({
@@ -33,37 +51,85 @@ export function generateSandbox(given) {
33
51
  fail('Unknown agent: ' + harnessName, 'Configured agents: ' + Object.keys(config.harnesses).join(', ')));
34
52
  if (!dirExists(workspaceHost))
35
53
  fail('The workspace folder does not exist: ' + workspaceHost, 'cd into the project first.');
54
+ // An engine or storage kind that cannot work yet stops the launch here, before anything is written.
55
+ const engine = opened ?? engineFor(config);
56
+ if (config.storage.contained !== 'off' && !o.dataMappings)
57
+ fail('Contained storage was not prepared for this launch.', 'Launch with sandbox launch (it mounts the image first).');
36
58
  assertTestWritable(storageRoot);
37
59
  assertTestWritable(dataPath);
38
60
  // Checked before anything is written, so a refusal leaves nothing behind.
39
- const memoryMb = Math.max(resolveMemoryMb(config.sandbox, o.freeMemoryBytes), ...others.map((p) => (typeof p.config.sandbox.memoryMb === 'number' ? p.config.sandbox.memoryMb : 0)));
61
+ const commitAvailableMb = o.commitAvailableMb ?? null;
62
+ const memoryMb = Math.max(resolveMemoryMb(config.sandbox, o.freeMemoryBytes, undefined, commitAvailableMb), ...others.map((p) => (typeof p.config.sandbox.memoryMb === 'number' ? p.config.sandbox.memoryMb : 0)));
40
63
  const launchId = Date.now() + '-' + crypto.randomBytes(3).toString('hex');
41
64
  const launchPath = path.join(storageRoot, 'launches', launchId);
42
- ensureDir(launchPath);
65
+ // Whatever must stay secret goes in a one-shot file in the data folder, never into the launch folder (the sandbox
66
+ // maps it read-only and it is kept for days). Leftovers of earlier launches go first.
43
67
  ensureDir(dataPath);
68
+ clearSecrets(storageRoot, dataPath);
69
+ ensureDir(launchPath);
44
70
  const mappingNotes = [];
45
71
  const mappings = collectMappings(o, launchPath, boot, mappingNotes);
46
72
  const profile = harnessName === 'claude'
47
73
  ? stageClaudeProfile(config.claudeProfile, launchPath, workspaceHost, config.secrets)
48
74
  : NO_PROFILE;
75
+ // This PC's Claude login leaves the launch folder for the one-shot file (with the agent environment and VPN login).
76
+ const claudeCredentials = takeStagedCredentials(launchPath);
49
77
  stageGitIdentity(launchPath);
50
78
  const personalization = config.personalization.enabled ? capturePersonalization(launchPath) : 'disabled';
51
79
  const databases = o.databases ?? planDatabases(config.databases, workspaceHost);
52
80
  const toolchains = decideProjectToolchains(o);
53
- const session = guestSession(o, { launchId, launchPath, harness, boot, mappings, profile, databases, toolchains });
81
+ if (o.vpn?.profile) {
82
+ ensureDir(path.join(launchPath, 'vpn'));
83
+ fs.writeFileSync(path.join(launchPath, 'vpn', 'server.ovpn'), o.vpn.profile, 'utf8');
84
+ }
85
+ const session = guestSession(o, {
86
+ launchId,
87
+ launchPath,
88
+ harness,
89
+ boot,
90
+ mappings,
91
+ profile,
92
+ databases,
93
+ toolchains,
94
+ memoryMb,
95
+ });
54
96
  const sessionPath = path.join(launchPath, 'session.json');
55
97
  writeJson(sessionPath, session);
98
+ writeLoadSettings(storageRoot, dataPath, {
99
+ profile: loadProfileOf(config),
100
+ reserveHostMb: config.sandbox.reserveHostMb,
101
+ });
102
+ writeSecrets(dataPath, launchId, {
103
+ ...(harness && Object.keys(harness.environment).length ? { harnessEnvironment: harness.environment } : {}),
104
+ ...(claudeCredentials ? { claudeCredentials } : {}),
105
+ ...(o.vpn?.credentials ? { vpn: o.vpn.credentials } : {}),
106
+ ...(o.vpn?.wireguardConfig ? { wireguardConfig: o.vpn.wireguardConfig } : {}),
107
+ });
56
108
  fs.writeFileSync(path.join(launchPath, 'env.cmd'), logonEnv(session.workspace), 'utf8');
57
109
  copyRuntime(o.packageRoot, launchPath);
58
110
  stageHooks(o.packageRoot, launchPath, o.run.scripts);
59
- const wsbPath = path.join(launchPath, 'agent.wsb');
60
- fs.writeFileSync(wsbPath, buildWsb(config, memoryMb, mappings), 'utf8');
111
+ const enginePlan = engine.plan(buildLaunchPlan({
112
+ config,
113
+ memoryMb,
114
+ mappings,
115
+ launchPath,
116
+ storage: o.dataMappings
117
+ ? o.dataMappings.map((m) => ({ kind: 'folder', host: m.host, guest: m.guest, readOnly: m.readOnly }))
118
+ : [folderAttachment({ dataPath, guest: GUEST.data })],
119
+ }));
120
+ for (const file of enginePlan.files)
121
+ fs.writeFileSync(file.path, file.text, 'utf8');
122
+ const wsbPath = enginePlan.entry;
61
123
  return {
62
124
  wsbPath,
125
+ enginePlan,
63
126
  launchPath,
64
127
  launchId,
65
128
  sessionPath,
66
129
  memoryMb,
130
+ memoryNote: config.sandbox.memoryMb === 'auto'
131
+ ? memoryNote(decideMemory(config.sandbox, Math.floor((o.freeMemoryBytes ?? os.freemem()) / 1048576), Math.floor(os.totalmem() / 1048576), commitAvailableMb))
132
+ : null,
67
133
  bootConfig: config,
68
134
  widened: wide.widened,
69
135
  mappings,
@@ -1,7 +1,9 @@
1
1
  export { generateSandbox } from './generate.js';
2
2
  export { decideProjectToolchains } from './toolchains.js';
3
3
  export { hostToolsOf, logonEnv } from './session-file.js';
4
- export { GUEST, buildWsb, resolveMemoryMb } from './wsb-file.js';
4
+ export { agentMemoryLimitMb, decideMemory, GUEST, memoryNote, resolveMemoryMb } from './wsb-file.js';
5
+ export { GENTLE_NOTE, vgpuSource, vgpuWarning } from './risk-notes.js';
6
+ export { buildLaunchPlan, buildWsb } from './launch-plan.js';
5
7
  export { MAX_BOOT_PROJECTS, planBootProjects, shownByRoot, type BootProjects } from './boot-projects.js';
6
8
  export { databaseCatalog, planDatabases } from './database-plan.js';
7
9
  export { msvcHint, projectEntries, readProjectFiles, uvHint } from './project-scan.js';
@@ -1,7 +1,9 @@
1
1
  export { generateSandbox } from './generate.js';
2
2
  export { decideProjectToolchains } from './toolchains.js';
3
3
  export { hostToolsOf, logonEnv } from './session-file.js';
4
- export { GUEST, buildWsb, resolveMemoryMb } from './wsb-file.js';
4
+ export { agentMemoryLimitMb, decideMemory, GUEST, memoryNote, resolveMemoryMb } from './wsb-file.js';
5
+ export { GENTLE_NOTE, vgpuSource, vgpuWarning } from './risk-notes.js';
6
+ export { buildLaunchPlan, buildWsb } from './launch-plan.js';
5
7
  export { MAX_BOOT_PROJECTS, planBootProjects, shownByRoot } from './boot-projects.js';
6
8
  export { databaseCatalog, planDatabases } from './database-plan.js';
7
9
  export { msvcHint, projectEntries, readProjectFiles, uvHint } from './project-scan.js';
@@ -0,0 +1,13 @@
1
+ import type { Config, ResolvedMapping } from '../../core/types.js';
2
+ import { type LaunchPlan } from '../engines/index.js';
3
+ import type { StorageAttachment } from '../storage/providers/index.js';
4
+ export interface LaunchPlanInput {
5
+ readonly config: Config;
6
+ readonly memoryMb: number;
7
+ readonly mappings: readonly ResolvedMapping[];
8
+ readonly launchPath: string;
9
+ readonly storage: readonly StorageAttachment[];
10
+ }
11
+ export declare function buildLaunchPlan(input: LaunchPlanInput): LaunchPlan;
12
+ /** The .wsb text for these settings (the Windows Sandbox engine's file, without writing it). */
13
+ export declare function buildWsb(config: Config, memoryMb: number, mappings: readonly ResolvedMapping[]): string;
@@ -0,0 +1,26 @@
1
+ import { wsbText } from '../engines/index.js';
2
+ import { GUEST } from './wsb-file.js';
3
+ export function buildLaunchPlan(input) {
4
+ const s = input.config.sandbox;
5
+ return {
6
+ launchPath: input.launchPath,
7
+ memoryMb: input.memoryMb,
8
+ cpuLimit: s.cpuLimit,
9
+ networking: s.networking,
10
+ devices: {
11
+ gpu: s.vGpu,
12
+ clipboard: s.clipboard,
13
+ audioInput: s.audioInput,
14
+ videoInput: s.videoInput,
15
+ printers: s.printerRedirection,
16
+ protectedClient: s.protectedClient,
17
+ },
18
+ mappings: input.mappings,
19
+ logonCommand: GUEST.launch + '\\sandbox\\boot\\logon.cmd',
20
+ storage: input.storage,
21
+ };
22
+ }
23
+ /** The .wsb text for these settings (the Windows Sandbox engine's file, without writing it). */
24
+ export function buildWsb(config, memoryMb, mappings) {
25
+ return wsbText(buildLaunchPlan({ config, memoryMb, mappings, launchPath: GUEST.launch, storage: [] }));
26
+ }
@@ -6,6 +6,7 @@ import { assertSafeMapping } from '../../core/safe-paths.js';
6
6
  import { dirExists, errMsg, fail, isInsideOrEqual, UserError } from '../../core/util/index.js';
7
7
  import { shownByRoot } from './boot-projects.js';
8
8
  import { deriveGuest, isValidGuestPath, guestConflict, guestFix, PROJECTS_GUEST, sandboxFolder, tidyGuestPath, } from '../../shared/paths/index.js';
9
+ import { dataMapping } from '../storage/providers/index.js';
9
10
  import { GUEST } from './wsb-file.js';
10
11
  import { guestGitDir, planView } from '../workspace-view/index.js';
11
12
  /**
@@ -23,7 +24,7 @@ export function collectMappings(o, launchPath, boot = { roots: [], projects: [],
23
24
  const inRoot = !view && shownByRoot(boot.roots, workspaceHost, config.guestWorkspace);
24
25
  const mappings = [
25
26
  { host: launchPath, guest: GUEST.launch, readOnly: true },
26
- { host: dataPath, guest: GUEST.data, readOnly: false },
27
+ ...(o.dataMappings ?? [dataMapping({ dataPath, guest: GUEST.data })]),
27
28
  ...(inRoot
28
29
  ? []
29
30
  : [{ host: view ? view.options.view : workspaceHost, guest: config.guestWorkspace, readOnly: config.readOnly }]),
@@ -0,0 +1,10 @@
1
+ import type { Config } from '../../core/types.js';
2
+ import type { LoadProfile } from '../../shared/memory/index.js';
3
+ /** The stricter load profile applies whenever vGPU is on, from any source. */
4
+ export declare function loadProfileOf(config: Config): LoadProfile;
5
+ /** Where vGpu being on comes from, for the sentence below: your own settings, or a project file you allowed. */
6
+ export declare function vgpuSource(yourSettingOn: boolean): string;
7
+ /** The vGPU warning (pure). `source` is vgpuSource(...) or "your settings". */
8
+ export declare function vgpuWarning(source: string): string;
9
+ /** The launch note that goes with the vGPU warning: what the tool does about it by itself. */
10
+ export declare const GENTLE_NOTE = "vGPU is on: the sandbox runs gentler so this PC stays responsive.";
@@ -0,0 +1,18 @@
1
+ // Plain-words warnings about settings that can take the whole PC down, shown at launch, by doctor and in crash reports.
2
+ /** The stricter load profile applies whenever vGPU is on, from any source. */
3
+ export function loadProfileOf(config) {
4
+ return config.sandbox.vGpu ? 'gentle' : 'normal';
5
+ }
6
+ /** Where vGpu being on comes from, for the sentence below: your own settings, or a project file you allowed. */
7
+ export function vgpuSource(yourSettingOn) {
8
+ return yourSettingOn ? 'your settings' : "this project's .sandbox-config.json, which you allowed";
9
+ }
10
+ /** The vGPU warning (pure). `source` is vgpuSource(...) or "your settings". */
11
+ export function vgpuWarning(source) {
12
+ return ('vGPU is on (from ' +
13
+ source +
14
+ "): the sandbox uses this PC's graphics card. With some graphics drivers, heavy use can freeze the whole PC. " +
15
+ 'Turn it off unless a program in the sandbox needs the GPU (the mesa toolchain gives software OpenGL without it).');
16
+ }
17
+ /** The launch note that goes with the vGPU warning: what the tool does about it by itself. */
18
+ export const GENTLE_NOTE = 'vGPU is on: the sandbox runs gentler so this PC stays responsive.';
@@ -10,6 +10,8 @@ export interface SessionParts {
10
10
  readonly profile: ProfileResult;
11
11
  readonly databases: DatabasePlan[];
12
12
  readonly toolchains: Generated['toolchains'];
13
+ /** The sandbox's memory (MB), for the agents' memory limit. */
14
+ readonly memoryMb: number;
13
15
  }
14
16
  /** What was found on this PC to copy instead of download. */
15
17
  export declare function hostToolsOf(probe: HostProbe): GuestSession['hostTools'];
@@ -5,6 +5,9 @@ import { resolveToolchains } from '../../core/detect/index.js';
5
5
  import { hubName, PROJECTS_GUEST, substDrives } from '../../shared/paths/index.js';
6
6
  import { hostClaudeDir } from '../profile/index.js';
7
7
  import { databaseCatalog } from './database-plan.js';
8
+ import { agentMemoryLimitMb } from './wsb-file.js';
9
+ import { effectiveCpuLimit } from '../../shared/memory/index.js';
10
+ import { loadProfileOf } from './risk-notes.js';
8
11
  /** What was found on this PC to copy instead of download. */
9
12
  export function hostToolsOf(probe) {
10
13
  return {
@@ -32,7 +35,8 @@ export function guestSession(o, parts) {
32
35
  roots: [...parts.boot.roots, ...parts.boot.projects].map((r) => r.guest),
33
36
  ...(o.autoSession === false ? { autoSession: false } : {}),
34
37
  harnessName,
35
- harness: parts.harness,
38
+ // The environment (it may hold API keys) travels in a one-shot file in <data>\secrets, never in this file.
39
+ harness: parts.harness ? { ...parts.harness, environment: {} } : null,
36
40
  harnessArguments: o.harnessArgs,
37
41
  persistAgentState: config.storage.persistAgentState,
38
42
  networking: config.sandbox.networking,
@@ -47,6 +51,7 @@ export function guestSession(o, parts) {
47
51
  attach: config.attach,
48
52
  hooks: config.hooks,
49
53
  downloads: config.downloads,
54
+ ...(o.vpn ? { vpn: o.vpn.session } : {}),
50
55
  hostTools: hostToolsOf(o.probe),
51
56
  claudeProfile: {
52
57
  overwrite: config.claudeProfile.overwrite,
@@ -57,12 +62,16 @@ export function guestSession(o, parts) {
57
62
  },
58
63
  personalization: fs.existsSync(path.join(parts.launchPath, 'personalize', 'personalize.reg')),
59
64
  substDrives: substDrives(parts.mappings.map((m) => m.guest)),
60
- cpuLimitPercent: config.sandbox.cpuLimit === 'none' ? null : config.sandbox.cpuLimit,
65
+ cpuLimitPercent: effectiveCpuLimit(config.sandbox.cpuLimit, loadProfileOf(config)),
66
+ loadProfile: loadProfileOf(config),
61
67
  pageFileMb: config.sandbox.pageFileMb,
68
+ agentMemoryLimitMb: agentMemoryLimitMb(parts.memoryMb, config.sandbox.agentMemoryHeadroomMb),
69
+ pressureResponse: config.sandbox.pressureResponse,
62
70
  apps: config.apps,
63
71
  auditProcesses: config.audit.enabled && config.audit.processes,
64
72
  agentHomes: Object.assign({}, ...Object.values(config.harnesses).map((h) => h.home?.env ?? {})),
65
73
  agentProfileDirs: Object.fromEntries(Object.entries(config.harnesses).flatMap(([name, h]) => h.home?.profileDirs?.length ? [[name, h.home.profileDirs]] : [])),
74
+ agents: Object.fromEntries(Object.entries(config.harnesses).map(([name, h]) => [name, { ...h, environment: {} }])),
66
75
  };
67
76
  }
68
77
  /**