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
@@ -4,10 +4,12 @@ import { isWithin, planMirrorWorkspace } from '../../../shared/paths/index.js';
4
4
  import { assertSafeMapping, assertSafeWorkspace } from '../../../core/safe-paths.js';
5
5
  import { isRootPath } from '../../../core/util/index.js';
6
6
  import { autoGuestWorkspace, placeInRoot } from '../../../core/run/index.js';
7
+ import { c } from '../../output/index.js';
7
8
  import { addToList, setSetting } from '../user-config.js';
8
9
  /**
9
- * Asked once per parent folder: map it at every start (a project root), so the projects next to this one open in the
10
- * running sandbox without a restart. The answer is saved to your config.
10
+ * Asked at a start from a folder whose parent is not shared yet ("Not now" asks again next time): map it at every
11
+ * start (a project root), so the projects next to this one open in the running sandbox without a restart. The answer is
12
+ * saved to your config.
11
13
  */
12
14
  export async function maybeAddRoot(ctx, run) {
13
15
  const { projects } = run.config;
@@ -27,23 +29,22 @@ export async function maybeAddRoot(ctx, run) {
27
29
  return;
28
30
  }
29
31
  const answer = await select({
30
- message: 'Map ' +
32
+ message: 'Share all projects in ' +
31
33
  parent +
32
- ' at every start, so other projects there (also new ones) open in the running sandbox without a restart? Agents in the sandbox can then see every project in it.',
34
+ ' with the sandbox?\n ' +
35
+ c.dim('Projects there, also new ones, then open without a restart. Agents can see every one of them.'),
33
36
  choices: [
34
- { name: 'Yes, from now on', value: 'yes' },
35
- { name: 'No (and do not ask again for this folder)', value: 'no' },
36
- { name: 'Never ask this again', value: 'never' },
37
+ { name: 'Yes, share ' + parent, value: 'yes' },
38
+ { name: 'Not now', value: 'no' },
39
+ { name: 'No, and stop asking', value: 'never' },
37
40
  ],
38
41
  });
39
42
  if (answer === 'yes') {
40
43
  addToList(ctx, ['projects', 'roots'], parent);
41
44
  run.config.projects.roots.push(parent);
42
- console.log('Added ' + parent + ' to projects.roots (sandbox projects roots remove ' + parent + ' undoes it).');
45
+ console.log('Added ' + parent + '. Undo: sandbox projects roots remove ' + parent);
43
46
  moveUnderRoot(run);
44
47
  }
45
- if (answer === 'no')
46
- addToList(ctx, ['projects', 'declinedRoots'], parent);
47
48
  if (answer === 'never')
48
49
  setSetting(ctx, ['projects', 'askToAddRoot'], false);
49
50
  }
@@ -3,12 +3,15 @@
3
3
  // restart that adds it is offered (restart.ts).
4
4
  import path from 'node:path';
5
5
  import _ from 'lodash';
6
- import { generateSandbox } from '../../../host/launch/index.js';
6
+ import { openEngine } from '../../../host/engines/index.js';
7
+ import { containedMappings, containedPaths, providerFor, setNameOf, } from '../../../host/storage/index.js';
8
+ import { generateSandbox, GUEST, vgpuSource, vgpuWarning } from '../../../host/launch/index.js';
7
9
  import { findSecretFiles } from '../../../host/profile/index.js';
8
10
  import { RepoGuardStore } from '../../../host/guard/index.js';
9
- import { assertCanLaunch, isSandboxRunning, spawnDetached, startSandbox, probeHost, hideSandboxWindow, } from '../../../host/sandbox/index.js';
11
+ import { hostPublicIp, prepareVpn, readVpnLine, vpnNotes } from '../../../host/vpn/index.js';
12
+ import { assertCanLaunch, isSandboxRunning, spawnDetached, probeHost, hideSandboxWindow, realContainedDeps, } from '../../../host/sandbox/index.js';
10
13
  import { KnownProjects, ProjectRegistry } from '../../../host/projects/index.js';
11
- import { LifeRecord, SessionLedger } from '../../../host/life/index.js';
14
+ import { LifeRecord, pageFileRisk, readHostMemory, SessionLedger, takePageFileHint } from '../../../host/life/index.js';
12
15
  import { isWithin } from '../../../shared/paths/index.js';
13
16
  import { watcherRunning } from '../../../sync/index.js';
14
17
  import { protectionsOf } from '../../../core/local-config/index.js';
@@ -19,6 +22,7 @@ import { c, table } from '../../output/index.js';
19
22
  import { syncAgentCommands } from '../agent-commands.js';
20
23
  import { requireOnPc } from '../context.js';
21
24
  import { joinHere } from '../projects/index.js';
25
+ import { offerSetupWhenOff } from '../setup/index.js';
22
26
  import { useSharedSandbox } from '../shared-use.js';
23
27
  import { beginSharing, currentUserName, currentUserSid, listProcesses, runningOwner, sessionOf, sharingDeps, takeSharingNotice, } from '../../../host/sharing/index.js';
24
28
  import { packageVersion } from '../../../core/package-info.js';
@@ -50,6 +54,11 @@ class Launcher {
50
54
  requireOnPc('launch');
51
55
  if (!generateOnly)
52
56
  this.syncAgentCommands();
57
+ if (!generateOnly) {
58
+ const setUp = await offerSetupWhenOff(this.ctx);
59
+ if (setUp !== undefined)
60
+ return setUp;
61
+ }
53
62
  if (!generateOnly && isSandboxRunning()) {
54
63
  // Another user's sandbox: an agent session in a project it has, when it is shared; nothing else.
55
64
  const ctx = await useSharedSandbox(this.ctx, options.noAgent ? { kind: 'owner-only', what: 'start a sandbox' } : { kind: 'use' });
@@ -111,28 +120,79 @@ class Launcher {
111
120
  }
112
121
  /** One sandbox for this folder: resolve, prepare, write the launch files, then (unless generate) start it. */
113
122
  async launchHere() {
114
- const { ctx, generateOnly, extras } = this;
123
+ const { ctx, generateOnly } = this;
115
124
  const run = await this.resolve();
116
125
  const { config } = run;
126
+ // An engine or storage kind that is not available yet stops here, before anything is prepared.
127
+ const engine = await openEngine(config);
128
+ const provider = providerFor(config, config.storage.contained === 'off'
129
+ ? {}
130
+ : { contained: realContainedDeps(ctx.storageRoot, config.storage.containedMaxGb) });
117
131
  if (!generateOnly)
118
132
  assertCanLaunch(isSandboxRunning() ? runningOwner() : undefined);
133
+ // Contained storage: the image is mounted now (before anything reads or writes the data set), and let go of again
134
+ // when the launch fails before the sandbox starts. The background watcher holds it from then on.
135
+ const dataMappings = await this.prepareStorage(provider, run);
136
+ try {
137
+ return await this.launchPrepared(run, engine, dataMappings);
138
+ }
139
+ catch (e) {
140
+ await provider.release();
141
+ throw e;
142
+ }
143
+ }
144
+ /** The data set's mappings from a contained-storage provider (mounting it), or undefined for plain folders. */
145
+ async prepareStorage(provider, run) {
146
+ if (provider.id === 'folder')
147
+ return undefined;
148
+ if (this.generateOnly)
149
+ return containedMappings(run.dataPath, containedPaths(run.storageRoot, setNameOf(run.dataPath)).mount, GUEST.data);
150
+ console.log('Mounting the contained storage (Windows asks for permission when it is not mounted yet)...');
151
+ return [...(await provider.prepare({ dataPath: run.dataPath, guest: GUEST.data })).mappings];
152
+ }
153
+ async launchPrepared(run, engine, dataMappings) {
154
+ const { ctx, generateOnly, extras } = this;
155
+ const { config } = run;
119
156
  if (!generateOnly && !extras.extraProjects)
120
157
  await maybeAddRoot(ctx, run);
121
158
  const prepared = generateOnly ? null : await prepare(ctx, run);
122
159
  const bootWants = await bootWantsFor(ctx, run, extras.extraProjects);
160
+ // The VPN (vpn.enabled): its server and profile are fetched and checked here, before anything is written.
161
+ const vpn = generateOnly
162
+ ? null
163
+ : await prepareVpn({
164
+ config,
165
+ storageRoot: ctx.storageRoot,
166
+ sandboxRunning: isSandboxRunning(),
167
+ base: run.workspaceHost,
168
+ });
169
+ // This PC's commit (RAM plus paging file) bounds the sandbox's memory as much as free RAM does.
170
+ const hostMemory = generateOnly ? null : readHostMemory(ctx.storageRoot);
123
171
  const generated = generateSandbox({
124
172
  packageRoot: ctx.packageRoot,
173
+ ...(hostMemory ? { commitAvailableMb: hostMemory.commitAvailableMb } : {}),
125
174
  run,
126
175
  harnessArgs: this.options.passthrough,
127
176
  probe: probeHost(config, run.harnessName),
128
177
  extraProjects: extras.extraProjects,
129
178
  autoSession: extras.autoSession,
130
179
  bootWants: bootWants.wants,
131
- });
180
+ ...(vpn ? { vpn } : {}),
181
+ ...(dataMappings ? { dataMappings } : {}),
182
+ }, engine);
132
183
  const notes = [...run.notes, ...bootWants.notes, ...generated.projects.notes, ...generated.mappingNotes];
133
184
  for (const note of notes)
134
185
  console.log(note);
186
+ if (generated.memoryNote)
187
+ console.log(c.yellow(generated.memoryNote));
188
+ if (generated.bootConfig.sandbox.vGpu)
189
+ console.log(c.yellow(vgpuWarning(vgpuSource(ctx.loaded.config.sandbox.vGpu))));
190
+ const risk = hostMemory ? pageFileRisk(hostMemory, generated.memoryMb) : null;
191
+ if (risk && takePageFileHint(ctx.storageRoot))
192
+ console.log(c.yellow(risk.text));
135
193
  this.warnSecretFiles(run);
194
+ for (const line of vpnNotes(config.vpn))
195
+ console.log(c.yellow(line));
136
196
  table(launchSummary(run, generated, prepared));
137
197
  if (generateOnly)
138
198
  return 0;
@@ -140,7 +200,7 @@ class Launcher {
140
200
  const reopen = extras.extraProjects ? [] : await sessionsToResume(ctx, run);
141
201
  this.record(run, generated);
142
202
  this.share(generated);
143
- startSandbox(generated.wsbPath);
203
+ await engine.start(generated.enginePlan);
144
204
  this.startWatcher();
145
205
  if (reopen.length)
146
206
  await this.reopenAfterBoot(generated.launchId, reopen);
@@ -188,8 +248,12 @@ class Launcher {
188
248
  */
189
249
  share(generated) {
190
250
  const deps = sharingDeps(this.ctx.packageRoot);
191
- if (!deps)
251
+ if (!deps) {
252
+ if (this.ctx.loaded.config.sharing.otherUsers)
253
+ console.log(c.yellow('This sandbox is not shared: sharing.otherUsers is on, but no all-users install was found on this PC. ' +
254
+ 'Install for everyone (install.ps1 -Scope AllUsers) to share sandboxes.'));
192
255
  return;
256
+ }
193
257
  // Only the shared tree may be opened to the group: never a storage folder of your own (your profile, say).
194
258
  const inSharedTree = isWithin(deps.usersDir, this.ctx.dataPath);
195
259
  if (this.ctx.loaded.config.sharing.otherUsers && !inSharedTree)
@@ -199,6 +263,9 @@ class Launcher {
199
263
  deps.usersDir +
200
264
  '. Remove storage.root from your config to use the shared folder.'));
201
265
  const shared = this.ctx.loaded.config.sharing.otherUsers && inSharedTree;
266
+ // Only an opened folder has permissions to write; a closed one is checked in a moment and usually needs nothing.
267
+ if (shared)
268
+ console.log('Setting folder permissions...');
202
269
  const rows = listProcesses();
203
270
  beginSharing(deps, {
204
271
  user: currentUserName(),
@@ -230,6 +297,26 @@ class Launcher {
230
297
  if (!watcherRunning(this.ctx.dataPath))
231
298
  spawnDetached(this.ctx.entry, ['_watch', ...(config ? ['--config', path.resolve(config)] : [])]);
232
299
  }
300
+ /** Waits for the boot; the VPN's outcome is said whether the boot worked or not (a failed tunnel can be why). */
301
+ async bootThenReportVpn(run, launchId, timed) {
302
+ try {
303
+ await waitForBoot(this.ctx.dataPath, launchId, timed);
304
+ }
305
+ catch (e) {
306
+ await this.reportVpn(run);
307
+ throw e;
308
+ }
309
+ await this.reportVpn(run);
310
+ }
311
+ /** Says whether the VPN came up (the sandbox reports it; its address is compared with this PC's). */
312
+ async reportVpn(run) {
313
+ if (!run.config.vpn.enabled)
314
+ return;
315
+ const line = readVpnLine(this.ctx.dataPath, await hostPublicIp());
316
+ if (!line)
317
+ return;
318
+ console.log(line.level === 'ok' ? c.green(line.text) : line.level === 'warn' ? c.yellow(line.text) : c.red(line.text));
319
+ }
233
320
  /** Waits for the boot and attaches when asked to; otherwise says where the agent opens. */
234
321
  async afterStart(run, generated) {
235
322
  const { ctx, options, extras } = this;
@@ -241,7 +328,7 @@ class Launcher {
241
328
  if (options.terminal || options.noAgent || extras.waitUntilReady) {
242
329
  if (headsUp)
243
330
  console.log(headsUp);
244
- await waitForBoot(dataPath, generated.launchId, Boolean(headsUp));
331
+ await this.bootThenReportVpn(run, generated.launchId, Boolean(headsUp));
245
332
  if (extras.waitUntilReady)
246
333
  return 0;
247
334
  // Without an agent there is no session to attach to: the sandbox itself is the result.
@@ -253,7 +340,13 @@ class Launcher {
253
340
  }
254
341
  return attachHere(ctx, await waitForStart(ctx, generated.launchId, 'Starting ' + run.harnessName));
255
342
  }
256
- if (headsUp)
343
+ // The VPN's outcome is worth waiting for: a failed tunnel with the kill switch on means no internet.
344
+ if (config.vpn.enabled) {
345
+ if (headsUp)
346
+ console.log(headsUp);
347
+ await this.bootThenReportVpn(run, generated.launchId, Boolean(headsUp));
348
+ }
349
+ else if (headsUp)
257
350
  console.log(headsUp + '\nFollow along: sandbox logs -f');
258
351
  if (hidden)
259
352
  console.log((await hidden)
@@ -2,7 +2,7 @@ import path from 'node:path';
2
2
  import fs from 'node:fs';
3
3
  import { AccountStore } from '../../../host/profile/index.js';
4
4
  import { SandboxChannel } from '../../../host/channel/index.js';
5
- import { describePrune, pruneStorage } from '../../../host/storage/index.js';
5
+ import { describePrune, hostDataFolder, pruneStorage } from '../../../host/storage/index.js';
6
6
  import { RepoGuardStore, readDataSize, saveMarkedProjects } from '../../../host/guard/index.js';
7
7
  import { ensureConpty, ensureTerminal } from '../../../host/tools/index.js';
8
8
  import { planView, viewSkipped, saveActiveViews, WorkspaceView } from '../../../host/workspace-view/index.js';
@@ -16,7 +16,7 @@ import { firstStartNotice, pendingDownloads } from './first-start.js';
16
16
  import { LifeRecord, UPDATE_RESTART_WARNING, updateRestartPending } from '../../../host/life/index.js';
17
17
  /** Nothing has been installed into this data set yet: the first start downloads every toolchain once. */
18
18
  export function firstBoot(dataPath) {
19
- return !fs.existsSync(path.join(dataPath, 'tools', 'resolved-versions.json'));
19
+ return !fs.existsSync(path.join(hostDataFolder(dataPath, 'tools'), 'resolved-versions.json'));
20
20
  }
21
21
  /** The first-start heads-up (also when this project needs tools not downloaded yet), or null. */
22
22
  export function firstBootNotice(dataPath, generated) {
@@ -27,7 +27,7 @@ export function firstBootNotice(dataPath, generated) {
27
27
  .map(([name]) => name),
28
28
  ...generated.databases.map((d) => d.database),
29
29
  ];
30
- return firstStartNotice(firstBoot(dataPath), pendingDownloads(wanted, (dir) => fs.existsSync(path.join(dataPath, 'tools', dir))));
30
+ return firstStartNotice(firstBoot(dataPath), pendingDownloads(wanted, (dir) => fs.existsSync(path.join(hostDataFolder(dataPath, 'tools'), dir))));
31
31
  }
32
32
  function syncSummary(config, dataPath, workspaceHost) {
33
33
  try {
@@ -77,10 +77,12 @@ async function prepareWorkspaceView(ctx, run) {
77
77
  export async function prepare(ctx, run) {
78
78
  const { options, dataPath, storageRoot } = ctx;
79
79
  const { config } = run;
80
- const accounts = new AccountStore(storageRoot);
80
+ const accounts = new AccountStore(storageRoot, config.claudeProfile.sharePluginsAcrossAccounts);
81
81
  const account = options.account ?? accounts.defaultName();
82
82
  if (account && run.harnessName === 'claude' && account !== accounts.activeFor(dataPath))
83
83
  accounts.activate(dataPath, account);
84
+ else if (run.harnessName === 'claude')
85
+ accounts.syncPlugins(dataPath);
84
86
  const terminal = config.provisioning.terminal.enabled
85
87
  ? await ensureTerminal(dataPath, config.provisioning.refresh, { pwsh: config.toolchains.pwsh.enabled !== false })
86
88
  : { exe: null, message: 'disabled' };
@@ -17,7 +17,8 @@ const SESSION_START_MS = 60 * 60 * 1000;
17
17
  export function attachHere(ctx, session) {
18
18
  if (ctx.loaded.config.attach.autoHide && !insideSandbox())
19
19
  void hideSandboxWindow(ctx.storageRoot, 120).catch(() => false);
20
- return attachTerminal(session);
20
+ // A copy in the agent reaches this PC's clipboard only when sandbox.clipboard already shares it with the sandbox.
21
+ return attachTerminal(session, { clipboardWrites: ctx.loaded.config.sandbox.clipboard });
21
22
  }
22
23
  /** The sandbox writes sandbox.json a few seconds into its boot; a second launch right after the first waits for it. */
23
24
  export async function runningSandboxStatus(dataPath) {
@@ -1,8 +1,10 @@
1
1
  import type { Generated, ResolvedRun } from '../../../core/types.js';
2
+ import type { EnginePlan } from '../../../host/engines/index.js';
2
3
  import type { Prepared } from './prepare.js';
3
4
  /** What generateSandbox returned. */
4
5
  export type GeneratedSandbox = Generated & {
5
6
  readonly personalization: string;
7
+ readonly enginePlan: EnginePlan;
6
8
  };
7
9
  /** The launch summary rows, in the order they are printed. */
8
10
  export declare function launchSummary(run: ResolvedRun, generated: GeneratedSandbox, prepared: Prepared | null): string[][];
@@ -28,7 +28,7 @@ export async function audit(ctx) {
28
28
  if (!events.length) {
29
29
  console.log(settings.enabled
30
30
  ? 'Nothing in the audit log for the last ' + ctx.options.days + ' day(s).'
31
- : 'The audit log is off. Turn it on in the menu (Settings > Security & privacy > Audit log) or with audit.enabled in your config.');
31
+ : 'The audit log is off. Turn it on in the menu (Settings > Security & privacy > Audit log) or with: sandbox config set audit.enabled true');
32
32
  return 0;
33
33
  }
34
34
  for (const e of events) {
@@ -1,2 +1,2 @@
1
1
  import { type Context } from '../context.js';
2
- export declare function clean(ctx: Context): number;
2
+ export declare function clean(ctx: Context): Promise<number>;
@@ -1,10 +1,24 @@
1
+ // `sandbox clean`: old launch folders, logs and leftovers. Shows what and how much, then asks (--yes skips).
1
2
  import _ from 'lodash';
3
+ import { askRequired } from '../../../core/prompt.js';
2
4
  import { describePrune, pruneStorage } from '../../../host/storage/index.js';
3
5
  import { isSandboxRunning } from '../../../host/sandbox/index.js';
4
6
  import { RunDir } from '../../../shared/channel/index.js';
5
- export function clean(ctx) {
7
+ import { nextStep } from '../../output/index.js';
8
+ export async function clean(ctx) {
6
9
  const running = isSandboxRunning() ? new RunDir(ctx.dataPath).readSandboxStatus()?.launchId : undefined;
7
- console.log('Cleanup: ' +
8
- describePrune(pruneStorage(ctx.storageRoot, { launchDays: ctx.options.days, keep: _.compact([running]) })));
10
+ const options = { launchDays: ctx.options.days, keep: _.compact([running]) };
11
+ const found = pruneStorage(ctx.storageRoot, { ...options, dryRun: true });
12
+ if (found.launches + found.logs + found.leftovers === 0) {
13
+ console.log('Nothing to clean.');
14
+ return 0;
15
+ }
16
+ console.log('Can be removed: ' + describePrune(found).replace(' removed', '') + '.');
17
+ if (!ctx.options.yes && !(await askRequired('Delete them?', 'Add --yes to delete without asking.'))) {
18
+ console.log('Nothing removed.');
19
+ return 1;
20
+ }
21
+ console.log('Removed ' + describePrune(pruneStorage(ctx.storageRoot, options)).replace(' removed', '') + '.');
22
+ nextStep('sandbox data (see what else is saved, and clean it)');
9
23
  return 0;
10
24
  }
@@ -0,0 +1,12 @@
1
+ import { type ImportPlan } from '../../menu/settings/index.js';
2
+ import type { Context } from '../context.js';
3
+ /** The file `config export` writes when none is named. */
4
+ export declare const DEFAULT_EXPORT = "sandbox-settings.json";
5
+ /** Writes the settings that differ from the defaults (no secrets, no storage, no paths unless asked) to `file`. */
6
+ export declare function writeExport(ctx: Context, file: string, withPaths: boolean, overwrite: boolean): string[];
7
+ /** Reads a shared file and plans the import. Fails with the reason when it cannot be read. */
8
+ export declare function readImport(ctx: Context, file: string): ImportPlan;
9
+ /** Writes the planned changes to your settings file (comments stay); returns how many settings changed. */
10
+ export declare function applyImport(ctx: Context, plan: ImportPlan): number;
11
+ export declare function exportCommand(ctx: Context, file: string | undefined): number;
12
+ export declare function importCommand(ctx: Context, file: string | undefined): Promise<number>;
@@ -0,0 +1,80 @@
1
+ // `sandbox config export` and `import`: your settings as a shareable .json, and a shared file read back in.
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { askRequired } from '../../../core/prompt.js';
5
+ import { fail, safeText, writeJson } from '../../../core/util/index.js';
6
+ import { c } from '../../output/index.js';
7
+ import { ConfigFile } from '../../../app/features/settings/index.js';
8
+ import { diffText, exportSettings, planImport, skippedLine } from '../../menu/settings/index.js';
9
+ /** The file `config export` writes when none is named. */
10
+ export const DEFAULT_EXPORT = 'sandbox-settings.json';
11
+ /** A shared file is a few KB; anything bigger is not one. */
12
+ const MAX_BYTES = 1024 * 1024;
13
+ /** Writes the settings that differ from the defaults (no secrets, no storage, no paths unless asked) to `file`. */
14
+ export function writeExport(ctx, file, withPaths, overwrite) {
15
+ const target = path.resolve(file);
16
+ if (!overwrite && fs.existsSync(target))
17
+ fail(target + ' exists already.', 'Pick another name, or delete it first.');
18
+ const { data, skipped } = exportSettings(ctx.loaded.config, withPaths);
19
+ fs.mkdirSync(path.dirname(target), { recursive: true });
20
+ writeJson(target, data);
21
+ return skipped.map(skippedLine);
22
+ }
23
+ /** Reads a shared file and plans the import. Fails with the reason when it cannot be read. */
24
+ export function readImport(ctx, file) {
25
+ const source = path.resolve(file);
26
+ if (!fs.existsSync(source))
27
+ fail('There is no file ' + source + '.', 'Give the path of a file made by sandbox config export.');
28
+ if (fs.statSync(source).size > MAX_BYTES)
29
+ fail(source + ' is too big to be a settings file.');
30
+ const plan = planImport(fs.readFileSync(source, 'utf8'), ctx.loaded.config);
31
+ if (plan.problems.length)
32
+ fail(source + ' is not valid settings:\n ' + plan.problems.map(safeText).join('\n '), 'Nothing was changed. Fix the file, or export a new one with: sandbox config export');
33
+ return plan;
34
+ }
35
+ /** Writes the planned changes to your settings file (comments stay); returns how many settings changed. */
36
+ export function applyImport(ctx, plan) {
37
+ const outcome = ConfigFile.user(ctx.loaded.configPath).setMany(plan.changes);
38
+ if (typeof outcome === 'object')
39
+ fail('Could not import: ' + outcome.problems.join('; '), 'Nothing was written. Your settings are unchanged.');
40
+ return plan.changes.length;
41
+ }
42
+ export function exportCommand(ctx, file) {
43
+ const target = file ?? DEFAULT_EXPORT;
44
+ const skipped = writeExport(ctx, target, ctx.options.withPaths, false);
45
+ console.log('Wrote ' + path.resolve(target) + ' (only what differs from the defaults).');
46
+ if (skipped.length) {
47
+ console.log('Left out:');
48
+ for (const line of skipped)
49
+ console.log(' ' + line);
50
+ }
51
+ if (!ctx.options.withPaths && skipped.some((s) => s.includes('folder or file')))
52
+ console.log("Keep this PC's folders and files in the file with --with-paths.");
53
+ return 0;
54
+ }
55
+ export async function importCommand(ctx, file) {
56
+ if (!file)
57
+ fail('Which file?', 'Usage: sandbox config import <file>');
58
+ const plan = readImport(ctx, file);
59
+ if (plan.skipped.length) {
60
+ console.log('Not imported (never taken from a file):');
61
+ for (const s of plan.skipped)
62
+ console.log(' ' + safeText(skippedLine(s)));
63
+ }
64
+ if (!plan.changes.length) {
65
+ console.log('Nothing to change: your settings already match the file.');
66
+ return 0;
67
+ }
68
+ console.log('This would change ' + plan.changes.length + ' setting' + (plan.changes.length === 1 ? '' : 's') + ':');
69
+ for (const line of diffText(plan.lines))
70
+ console.log(' ' + safeText(line));
71
+ const yes = ctx.options.yes ||
72
+ (await askRequired('Change your settings like this?', 'Add --yes to change them without asking.'));
73
+ if (!yes) {
74
+ console.log('Nothing was changed.');
75
+ return 0;
76
+ }
77
+ const n = applyImport(ctx, plan);
78
+ console.log(c.green('Imported ' + n + ' setting' + (n === 1 ? '' : 's') + '.') + ' New sandboxes use them.');
79
+ return 0;
80
+ }
@@ -1,2 +1,2 @@
1
1
  import { type Context } from '../context.js';
2
- export declare function config(ctx: Context): number;
2
+ export declare function config(ctx: Context): number | Promise<number>;
@@ -1,21 +1,44 @@
1
+ import { spawn } from 'node:child_process';
1
2
  import fs from 'node:fs';
2
3
  import path from 'node:path';
3
4
  import { pathToFileURL } from 'node:url';
4
5
  import { DEFAULTS, userConfigPath, userDir } from '../../../core/config/index.js';
6
+ import { redactSecrets } from '../../../core/schema/index.js';
5
7
  import { allowedAnswer, allowStorePath, applyOverrides, describeOverrides, isTrusted, LOCAL_CONFIG_NAME, loosenedRequests, normalizeOverrides, OUTSIDE_FOLDER, outsideKey, outsideMappings, readLocalConfig, trustStorePath, } from '../../../core/local-config/index.js';
6
8
  import { guestWorkspaceOf, previewGuest } from '../../../core/run/index.js';
9
+ import { askChoice } from '../../../core/prompt.js';
7
10
  import { dirExists, fail, safeText, writeJson } from '../../../core/util/index.js';
8
- import { c, table } from '../../output/index.js';
9
- function initConfig() {
11
+ import { system32 } from '../../../shared/system.js';
12
+ import { refuseInSelfTest } from '../../../host/test-guard.js';
13
+ import { c, nextStep, table } from '../../output/index.js';
14
+ import { exportCommand, importCommand } from './config-share.js';
15
+ /** The settings file exists already: open it, start over, or leave it (no terminal: say how). */
16
+ async function existingFile(file) {
17
+ return askChoice(file + ' exists already.', [
18
+ { name: 'Open it', value: 'open' },
19
+ { name: 'Overwrite it with the defaults (your changes are lost)', value: 'overwrite' },
20
+ { name: 'Cancel', value: 'cancel' },
21
+ ], 'Open it with: sandbox config path. To start over, delete it first.');
22
+ }
23
+ async function initConfig() {
10
24
  const file = userConfigPath();
11
- if (fs.existsSync(file))
12
- fail(file + ' already exists.');
25
+ if (fs.existsSync(file)) {
26
+ const answer = await existingFile(file);
27
+ if (answer === 'cancel')
28
+ return 0;
29
+ if (answer === 'open') {
30
+ refuseInSelfTest('open files');
31
+ spawn(system32('notepad.exe'), [file], { detached: true, stdio: 'ignore' }).unref();
32
+ console.log('Opened ' + file + '.');
33
+ return 0;
34
+ }
35
+ }
13
36
  fs.mkdirSync(path.join(userDir(), 'hooks', 'pre-agent'), { recursive: true });
14
37
  // The schema sits next to the file (a local path), so editors trust it and show docs and autocomplete.
15
38
  writeJson(file, { $schema: './config.schema.json', ...DEFAULTS });
16
39
  console.log('Created ' + file + '. It lists every setting with its default; delete the ones you do not change.');
17
40
  console.log('Your own hook scripts go in ' + path.join(userDir(), 'hooks') + '\\{pre-provision,pre-agent,post-agent}.');
18
- console.log("For editor help in every project's .sandbox-config.json, run: sandbox config schema");
41
+ nextStep("sandbox config schema (editor help in every project's .sandbox-config.json)");
19
42
  return 0;
20
43
  }
21
44
  /**
@@ -72,9 +95,9 @@ function previewFolders(ctx, dir, filePath, overrides) {
72
95
  if (!outside.includes(m))
73
96
  return m.guest ? 'inside the project' : 'inside the project (already in the sandbox there)';
74
97
  if (policy === true)
75
- return 'outside the project, allowed (projects.allowOutsideMappings is true)';
98
+ return 'outside the project, allowed (your settings allow it)';
76
99
  if (policy === false)
77
- return c.red('outside the project: refused (projects.allowOutsideMappings is false)');
100
+ return c.red('outside the project: refused (your settings do not allow it)');
78
101
  return allowedAnswer(store, filePath, OUTSIDE_FOLDER, outsideKey(m)) === true
79
102
  ? 'outside the project, allowed (you said yes)'
80
103
  : c.yellow('outside the project: the next interactive launch asks you');
@@ -110,7 +133,8 @@ function previewFolders(ctx, dir, filePath, overrides) {
110
133
  }
111
134
  }
112
135
  export function config(ctx) {
113
- const [action = 'summary'] = ctx.options.positionals;
136
+ // get, set, reset and list are the settings feature's operations (cli/operations runs them before this).
137
+ const [action = 'summary', key] = ctx.options.positionals;
114
138
  switch (action) {
115
139
  case 'summary':
116
140
  table([
@@ -133,13 +157,17 @@ export function config(ctx) {
133
157
  case 'init':
134
158
  return initConfig();
135
159
  case 'show':
136
- console.log(JSON.stringify(ctx.loaded.config, null, 2));
160
+ console.log(JSON.stringify(redactSecrets(ctx.loaded.config), null, 2));
137
161
  return 0;
162
+ case 'export':
163
+ return exportCommand(ctx, key);
164
+ case 'import':
165
+ return importCommand(ctx, key);
138
166
  case 'schema':
139
167
  return printSchemaSettings();
140
168
  case 'check':
141
169
  return checkLocalConfig(ctx);
142
170
  default:
143
- fail('Unknown config action "' + action + '".', 'Use one of: sandbox config show | path | init | schema | check');
171
+ fail('Unknown config action "' + action + '".', 'Use one of: sandbox config show | list | get | set | reset | path | init | schema | check | export | import');
144
172
  }
145
173
  }
@@ -1,2 +1,2 @@
1
1
  import { type Context } from '../context.js';
2
- export declare function doctor(ctx: Context): number;
2
+ export declare function doctor(ctx: Context): Promise<number>;
@@ -1,6 +1,4 @@
1
- import { table } from '../../output/index.js';
2
- import { HealthService } from '../../services/index.js';
1
+ import { runDoctor } from '../repair/index.js';
3
2
  export function doctor(ctx) {
4
- table(new HealthService(ctx).doctor());
5
- return 0;
3
+ return runDoctor(ctx);
6
4
  }
@@ -1,6 +1,20 @@
1
1
  import { sleep } from '../../../core/util/index.js';
2
+ import { newestCrashReport } from '../../../host/life/index.js';
2
3
  import { LogsService } from '../../services/index.js';
4
+ /** The newest crash report (written by the background sync when the sandbox or this PC went down). */
5
+ function printCrashReport(ctx) {
6
+ const report = newestCrashReport(ctx.storageRoot);
7
+ if (!report) {
8
+ console.log('No crash report yet: no sandbox has ended in a crash since this was installed.');
9
+ return 0;
10
+ }
11
+ console.log('== ' + report.file + ' ==');
12
+ console.log(report.text);
13
+ return 0;
14
+ }
3
15
  export async function logs(ctx) {
16
+ if (ctx.options.crash)
17
+ return printCrashReport(ctx);
4
18
  const service = new LogsService(ctx);
5
19
  const file = service.newest();
6
20
  console.log('== ' + file + ' ==');
@@ -1,9 +1,10 @@
1
1
  import { MigrateService } from '../../services/index.js';
2
- import type { Context } from '../context.js';
2
+ import { type Context } from '../context.js';
3
3
  /** `sandbox migrate`: the work, with the service and the output given so a test can drive it. */
4
4
  export declare function runMigrate(service: MigrateService, options: {
5
5
  readonly dryRun: boolean;
6
6
  readonly restore?: string;
7
+ readonly yes?: boolean;
7
8
  }, print: (line: string) => void): Promise<number>;
8
9
  export declare function migrate(ctx: Context): Promise<number>;
9
10
  /**