windows-development-sandbox 1.10.0 → 1.11.3

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 (378) hide show
  1. package/README.md +64 -17
  2. package/config.example.json +5 -1
  3. package/dist/app/features/accounts/accounts.def.d.ts +122 -0
  4. package/dist/app/features/accounts/accounts.def.js +243 -0
  5. package/dist/app/features/accounts/accounts.run.d.ts +51 -0
  6. package/dist/app/features/accounts/accounts.run.js +125 -0
  7. package/dist/app/features/accounts/index.d.ts +2 -0
  8. package/dist/app/features/accounts/index.js +3 -0
  9. package/dist/app/features/agents/agent-entry.d.ts +17 -0
  10. package/dist/app/features/agents/agent-entry.js +50 -0
  11. package/dist/app/features/agents/agents.def.d.ts +65 -0
  12. package/dist/app/features/agents/agents.def.js +142 -0
  13. package/dist/app/features/agents/agents.run.d.ts +31 -0
  14. package/dist/app/features/agents/agents.run.js +189 -0
  15. package/dist/app/features/agents/index.d.ts +3 -0
  16. package/dist/app/features/agents/index.js +4 -0
  17. package/dist/app/features/apps/apps-rows.d.ts +31 -0
  18. package/dist/app/features/apps/apps-rows.js +73 -0
  19. package/dist/app/features/apps/apps.def.d.ts +181 -0
  20. package/dist/app/features/apps/apps.def.js +264 -0
  21. package/dist/app/features/apps/apps.run.d.ts +58 -0
  22. package/dist/app/features/apps/apps.run.js +76 -0
  23. package/dist/app/features/apps/index.d.ts +3 -0
  24. package/dist/app/features/apps/index.js +4 -0
  25. package/dist/app/features/data/data.def.d.ts +154 -0
  26. package/dist/app/features/data/data.def.js +201 -0
  27. package/dist/app/features/data/data.run.d.ts +46 -0
  28. package/dist/app/features/data/data.run.js +141 -0
  29. package/dist/app/features/data/index.d.ts +2 -0
  30. package/dist/app/features/data/index.js +3 -0
  31. package/dist/app/features/defs.d.ts +952 -4
  32. package/dist/app/features/defs.js +147 -10
  33. package/dist/app/features/engine/engine.def.d.ts +228 -0
  34. package/dist/app/features/engine/engine.def.js +194 -0
  35. package/dist/app/features/engine/engine.run.d.ts +72 -0
  36. package/dist/app/features/engine/engine.run.js +77 -0
  37. package/dist/app/features/engine/index.d.ts +2 -0
  38. package/dist/app/features/engine/index.js +4 -0
  39. package/dist/app/features/files/files.def.d.ts +51 -0
  40. package/dist/app/features/files/files.def.js +38 -0
  41. package/dist/app/features/files/files.run.d.ts +20 -0
  42. package/dist/app/features/files/files.run.js +59 -0
  43. package/dist/app/features/files/index.d.ts +2 -0
  44. package/dist/app/features/files/index.js +3 -0
  45. package/dist/app/features/github/github.def.d.ts +80 -0
  46. package/dist/app/features/github/github.def.js +142 -0
  47. package/dist/app/features/github/github.run.d.ts +36 -0
  48. package/dist/app/features/github/github.run.js +59 -0
  49. package/dist/app/features/github/index.d.ts +2 -0
  50. package/dist/app/features/github/index.js +3 -0
  51. package/dist/app/features/health/health.def.d.ts +275 -0
  52. package/dist/app/features/health/health.def.js +281 -0
  53. package/dist/app/features/health/health.run.d.ts +125 -0
  54. package/dist/app/features/health/health.run.js +204 -0
  55. package/dist/app/features/health/index.d.ts +2 -0
  56. package/dist/app/features/health/index.js +3 -0
  57. package/dist/app/features/logs/index.d.ts +2 -0
  58. package/dist/app/features/logs/index.js +3 -0
  59. package/dist/app/features/logs/logs.def.d.ts +78 -0
  60. package/dist/app/features/logs/logs.def.js +115 -0
  61. package/dist/app/features/logs/logs.run.d.ts +20 -0
  62. package/dist/app/features/logs/logs.run.js +42 -0
  63. package/dist/app/features/projects/index.d.ts +2 -0
  64. package/dist/app/features/projects/index.js +3 -0
  65. package/dist/app/features/projects/projects.def.d.ts +101 -0
  66. package/dist/app/features/projects/projects.def.js +208 -0
  67. package/dist/app/features/projects/projects.run.d.ts +56 -0
  68. package/dist/app/features/projects/projects.run.js +155 -0
  69. package/dist/app/features/sandbox/sandbox.def.js +11 -5
  70. package/dist/app/features/sessions/sessions.def.js +3 -0
  71. package/dist/app/features/settings/categories.def.js +3 -2
  72. package/dist/{cli/menu/settings/share.d.ts → app/features/settings/settings-share.d.ts} +1 -1
  73. package/dist/{cli/menu/settings/share.js → app/features/settings/settings-share.js} +3 -2
  74. package/dist/app/features/settings/settings.def.d.ts +22 -5
  75. package/dist/app/features/settings/settings.def.js +81 -6
  76. package/dist/app/features/settings/settings.run.d.ts +17 -0
  77. package/dist/app/features/settings/settings.run.js +89 -4
  78. package/dist/app/features/storage/index.d.ts +2 -0
  79. package/dist/app/features/storage/index.js +3 -0
  80. package/dist/app/features/storage/storage.def.d.ts +133 -0
  81. package/dist/app/features/storage/storage.def.js +225 -0
  82. package/dist/app/features/storage/storage.run.d.ts +62 -0
  83. package/dist/app/features/storage/storage.run.js +370 -0
  84. package/dist/app/features/updates/index.d.ts +3 -0
  85. package/dist/app/features/updates/index.js +4 -0
  86. package/dist/app/features/updates/update-lines.d.ts +13 -0
  87. package/dist/app/features/updates/update-lines.js +61 -0
  88. package/dist/app/features/updates/updates.def.d.ts +89 -0
  89. package/dist/app/features/updates/updates.def.js +225 -0
  90. package/dist/app/features/updates/updates.run.d.ts +48 -0
  91. package/dist/app/features/updates/updates.run.js +154 -0
  92. package/dist/app/features/vpn/index.d.ts +2 -0
  93. package/dist/app/features/vpn/index.js +3 -0
  94. package/dist/app/features/vpn/vpn.def.d.ts +112 -0
  95. package/dist/app/features/vpn/vpn.def.js +174 -0
  96. package/dist/app/features/vpn/vpn.run.d.ts +37 -0
  97. package/dist/app/features/vpn/vpn.run.js +54 -0
  98. package/dist/app/features/web/index.d.ts +2 -0
  99. package/dist/app/features/web/index.js +3 -0
  100. package/dist/app/features/web/web.def.d.ts +33 -0
  101. package/dist/app/features/web/web.def.js +90 -0
  102. package/dist/app/features/web/web.run.d.ts +24 -0
  103. package/dist/app/features/web/web.run.js +93 -0
  104. package/dist/app/kernel/define.d.ts +10 -1
  105. package/dist/app/kernel/io.d.ts +34 -0
  106. package/dist/app/kernel/io.js +9 -0
  107. package/dist/app/kernel/rpc.d.ts +17 -0
  108. package/dist/app/kernel/text.d.ts +2 -0
  109. package/dist/app/kernel/text.js +7 -0
  110. package/dist/app/kernel/view.d.ts +24 -1
  111. package/dist/app/kernel/view.js +1 -1
  112. package/dist/app/registry.js +74 -1
  113. package/dist/cli/args.js +1 -1
  114. package/dist/cli/commands/context.d.ts +7 -0
  115. package/dist/cli/commands/context.js +29 -2
  116. package/dist/cli/commands/engine.js +5 -58
  117. package/dist/cli/commands/github.d.ts +2 -0
  118. package/dist/cli/commands/github.js +11 -0
  119. package/dist/cli/commands/index.d.ts +3 -5
  120. package/dist/cli/commands/index.js +3 -5
  121. package/dist/cli/commands/launch/launch.js +21 -4
  122. package/dist/cli/commands/launch/running.js +4 -1
  123. package/dist/cli/commands/maintenance/config.js +1 -6
  124. package/dist/cli/commands/maintenance/index.d.ts +0 -1
  125. package/dist/cli/commands/maintenance/index.js +1 -2
  126. package/dist/cli/commands/maintenance/logs.js +27 -32
  127. package/dist/cli/commands/maintenance/migrate.d.ts +0 -8
  128. package/dist/cli/commands/maintenance/migrate.js +2 -44
  129. package/dist/cli/commands/maintenance/update.d.ts +0 -19
  130. package/dist/cli/commands/maintenance/update.js +1 -99
  131. package/dist/cli/commands/projects/index.d.ts +0 -1
  132. package/dist/cli/commands/projects/index.js +0 -1
  133. package/dist/cli/commands/registry.d.ts +1 -1
  134. package/dist/cli/commands/registry.js +29 -11
  135. package/dist/cli/commands/repair/checks/data.js +1 -1
  136. package/dist/cli/commands/repair/checks/hcs.js +28 -1
  137. package/dist/cli/commands/repair/checks/sandbox.js +1 -1
  138. package/dist/cli/commands/repair/health-run.d.ts +30 -0
  139. package/dist/cli/commands/repair/health-run.js +32 -0
  140. package/dist/cli/commands/repair/printer.d.ts +2 -2
  141. package/dist/cli/commands/repair/printer.js +2 -11
  142. package/dist/cli/commands/repair/run.d.ts +1 -21
  143. package/dist/cli/commands/repair/run.js +13 -70
  144. package/dist/cli/commands/storage/index.d.ts +0 -1
  145. package/dist/cli/commands/storage/index.js +0 -1
  146. package/dist/cli/commands/storage/offer.js +6 -2
  147. package/dist/cli/commands/vpn.d.ts +1 -3
  148. package/dist/cli/commands/vpn.js +8 -89
  149. package/dist/cli/commands/web.d.ts +2 -1
  150. package/dist/cli/commands/web.js +14 -78
  151. package/dist/cli/index.js +3 -2
  152. package/dist/cli/manifest.d.ts +16 -153
  153. package/dist/cli/manifest.js +20 -50
  154. package/dist/cli/menu/command-form.js +1 -2
  155. package/dist/cli/menu/io-menu.d.ts +2 -2
  156. package/dist/cli/menu/io-menu.js +6 -4
  157. package/dist/cli/menu/menu.js +1 -1
  158. package/dist/cli/menu/pages/accounts-page.d.ts +5 -17
  159. package/dist/cli/menu/pages/accounts-page.js +28 -170
  160. package/dist/cli/menu/pages/agents-page.d.ts +17 -18
  161. package/dist/cli/menu/pages/agents-page.js +67 -124
  162. package/dist/cli/menu/pages/apps-page.d.ts +15 -8
  163. package/dist/cli/menu/pages/apps-page.js +121 -29
  164. package/dist/cli/menu/pages/list-page.js +10 -1
  165. package/dist/cli/menu/pages/maintenance-page.d.ts +51 -52
  166. package/dist/cli/menu/pages/maintenance-page.js +246 -427
  167. package/dist/cli/menu/pages/sandbox-page.d.ts +3 -5
  168. package/dist/cli/menu/pages/sandbox-page.js +34 -112
  169. package/dist/cli/menu/pages/settings-page.d.ts +21 -3
  170. package/dist/cli/menu/pages/settings-page.js +89 -17
  171. package/dist/cli/menu/render-view.js +2 -1
  172. package/dist/cli/menu/settings/index.d.ts +0 -1
  173. package/dist/cli/menu/settings/index.js +3 -3
  174. package/dist/cli/menu/views.js +28 -0
  175. package/dist/cli/operations/handler.js +7 -3
  176. package/dist/cli/operations/input.d.ts +1 -1
  177. package/dist/cli/operations/input.js +29 -5
  178. package/dist/cli/operations/io-cli.js +9 -1
  179. package/dist/cli/operations/spec.js +8 -2
  180. package/dist/cli/output/render-view.js +2 -0
  181. package/dist/cli/{commands/data/collect.js → services/data-collect.js} +2 -2
  182. package/dist/cli/{commands/data/remove.js → services/data-remove.js} +2 -2
  183. package/dist/cli/services/data-service.d.ts +1 -1
  184. package/dist/cli/services/data-service.js +2 -2
  185. package/dist/cli/services/databases-service.d.ts +5 -0
  186. package/dist/cli/services/databases-service.js +15 -0
  187. package/dist/cli/services/health-service.d.ts +8 -4
  188. package/dist/cli/services/health-service.js +10 -8
  189. package/dist/cli/services/index.d.ts +4 -1
  190. package/dist/cli/services/index.js +4 -1
  191. package/dist/cli/services/logs-service.d.ts +7 -0
  192. package/dist/cli/services/logs-service.js +13 -0
  193. package/dist/cli/services/storage-service.d.ts +19 -0
  194. package/dist/cli/services/storage-service.js +71 -0
  195. package/dist/cli/services/vpn-service.d.ts +6 -4
  196. package/dist/cli/services/vpn-service.js +5 -11
  197. package/dist/cli/services/web-service.d.ts +4 -3
  198. package/dist/cli/services/web-service.js +12 -32
  199. package/dist/core/config/defaults.js +2 -1
  200. package/dist/core/schema/config.d.ts +5 -0
  201. package/dist/core/schema/config.js +2 -0
  202. package/dist/core/schema/github.d.ts +4 -0
  203. package/dist/core/schema/github.js +7 -0
  204. package/dist/core/schema/index.d.ts +1 -0
  205. package/dist/core/schema/index.js +1 -0
  206. package/dist/core/schema/profile.d.ts +1 -0
  207. package/dist/core/schema/profile.js +3 -0
  208. package/dist/core/schema/sandbox.js +3 -3
  209. package/dist/core/schema/toolchains.js +2 -2
  210. package/dist/core/types.d.ts +6 -3
  211. package/dist/guest/boot/boot.js +8 -0
  212. package/dist/guest/daemon/daemon.js +1 -1
  213. package/dist/guest/daemon/sessions.d.ts +3 -2
  214. package/dist/guest/daemon/sessions.js +38 -7
  215. package/dist/guest/governor/core.d.ts +44 -0
  216. package/dist/guest/governor/core.js +124 -0
  217. package/dist/guest/governor/decide.d.ts +46 -18
  218. package/dist/guest/governor/decide.js +136 -82
  219. package/dist/guest/governor/governor.d.ts +2 -38
  220. package/dist/guest/governor/governor.js +33 -113
  221. package/dist/guest/governor/index.d.ts +1 -0
  222. package/dist/guest/governor/index.js +1 -0
  223. package/dist/guest/network/firewall.d.ts +2 -0
  224. package/dist/guest/network/firewall.js +3 -3
  225. package/dist/guest/sessions/viewer.js +5 -1
  226. package/dist/guest/setup/github-token.d.ts +7 -0
  227. package/dist/guest/setup/github-token.js +65 -0
  228. package/dist/guest/toolchains/languages/node.js +11 -1
  229. package/dist/guest/toolchains/native/rust-extras.js +2 -2
  230. package/dist/guest/toolchains/tools/cli.d.ts +8 -0
  231. package/dist/guest/toolchains/tools/cli.js +16 -2
  232. package/dist/guest/vpn/openvpn.d.ts +5 -0
  233. package/dist/guest/vpn/openvpn.js +14 -1
  234. package/dist/guest/vpn/vpn.js +55 -16
  235. package/dist/guest/vpn/wireguard.js +2 -0
  236. package/dist/host/channel/attach.d.ts +1 -0
  237. package/dist/host/channel/attach.js +1 -0
  238. package/dist/host/channel/channel.d.ts +1 -1
  239. package/dist/host/channel/channel.js +2 -2
  240. package/dist/host/engines/hcs/check.d.ts +1 -0
  241. package/dist/host/engines/hcs/check.js +1 -1
  242. package/dist/host/engines/hcs/engine.d.ts +1 -1
  243. package/dist/host/engines/hcs/engine.js +6 -4
  244. package/dist/host/engines/hcs/helper.d.ts +11 -0
  245. package/dist/host/engines/hcs/helper.js +31 -2
  246. package/dist/host/engines/hcs/leftovers.d.ts +42 -0
  247. package/dist/host/engines/hcs/leftovers.js +101 -0
  248. package/dist/host/engines/index.d.ts +1 -0
  249. package/dist/host/engines/index.js +1 -0
  250. package/dist/host/github/deliver.d.ts +13 -0
  251. package/dist/host/github/deliver.js +51 -0
  252. package/dist/host/github/index.d.ts +2 -0
  253. package/dist/host/github/index.js +3 -0
  254. package/dist/host/github/token.d.ts +21 -0
  255. package/dist/host/github/token.js +74 -0
  256. package/dist/host/launch/generate.js +11 -5
  257. package/dist/host/launch/index.d.ts +1 -1
  258. package/dist/host/launch/index.js +1 -1
  259. package/dist/host/launch/session-file.js +1 -2
  260. package/dist/host/launch/wsb-file.d.ts +11 -7
  261. package/dist/host/launch/wsb-file.js +30 -12
  262. package/dist/host/life/watchdog.d.ts +9 -0
  263. package/dist/host/life/watchdog.js +17 -1
  264. package/dist/host/sandbox/tasklist.d.ts +6 -0
  265. package/dist/host/sandbox/tasklist.js +37 -0
  266. package/dist/host/secrets/launch-secrets.d.ts +2 -1
  267. package/dist/host/secrets/launch-secrets.js +4 -2
  268. package/dist/host/vpn/status.js +13 -3
  269. package/dist/host/web/backend.d.ts +1 -3
  270. package/dist/host/web/index.d.ts +2 -1
  271. package/dist/host/web/index.js +2 -1
  272. package/dist/host/web/live.d.ts +23 -0
  273. package/dist/host/web/live.js +107 -0
  274. package/dist/host/web/rpc.d.ts +6 -1
  275. package/dist/host/web/rpc.js +23 -31
  276. package/dist/host/web/runner.d.ts +4 -0
  277. package/dist/host/web/runner.js +12 -1
  278. package/dist/host/web/server.d.ts +30 -2
  279. package/dist/host/web/server.js +87 -29
  280. package/dist/host/web/state.d.ts +1 -0
  281. package/dist/host/web/state.js +2 -0
  282. package/dist/runtime/agent.js +30 -6
  283. package/dist/runtime/daemon.js +323 -176
  284. package/dist/runtime/db.js +30 -6
  285. package/dist/runtime/main.js +375 -76
  286. package/dist/runtime/netproxy.js +30 -6
  287. package/dist/runtime/view.js +495 -146
  288. package/dist/selftest/app.test.js +620 -12
  289. package/dist/selftest/channel.test.js +18 -1
  290. package/dist/selftest/cli.test.js +1 -1
  291. package/dist/selftest/config.test.js +1 -1
  292. package/dist/selftest/contained.test.js +1 -1
  293. package/dist/selftest/data.test.js +1 -2
  294. package/dist/selftest/engine.test.js +3 -1
  295. package/dist/selftest/github.test.d.ts +2 -0
  296. package/dist/selftest/github.test.js +243 -0
  297. package/dist/selftest/hcs.test.js +105 -8
  298. package/dist/selftest/health.test.js +71 -0
  299. package/dist/selftest/heavy-load.test.js +132 -72
  300. package/dist/selftest/index.js +4 -0
  301. package/dist/selftest/layout.test.js +8 -0
  302. package/dist/selftest/live-terminal.test.js +74 -0
  303. package/dist/selftest/menu-screens.js +171 -56
  304. package/dist/selftest/menu.test.js +54 -37
  305. package/dist/selftest/migrate.test.js +14 -12
  306. package/dist/selftest/powershell-variables.test.d.ts +2 -0
  307. package/dist/selftest/powershell-variables.test.js +61 -0
  308. package/dist/selftest/support/engine-golden.js +1 -0
  309. package/dist/selftest/support/fixtures.d.ts +4 -0
  310. package/dist/selftest/support/web-preview.d.ts +1 -0
  311. package/dist/selftest/support/web-preview.js +856 -0
  312. package/dist/selftest/update-service.test.js +15 -8
  313. package/dist/selftest/vpn.test.js +86 -2
  314. package/dist/selftest/web.test.js +58 -11
  315. package/dist/shared/channel/run-dir.d.ts +2 -0
  316. package/dist/shared/channel/run-dir.js +3 -0
  317. package/dist/shared/channel/schema.d.ts +7 -0
  318. package/dist/shared/channel/schema.js +9 -1
  319. package/dist/shared/channel/secrets.d.ts +1 -0
  320. package/dist/shared/channel/secrets.js +3 -0
  321. package/dist/shared/github/index.d.ts +1 -0
  322. package/dist/shared/github/index.js +2 -0
  323. package/dist/shared/github/token.d.ts +29 -0
  324. package/dist/shared/github/token.js +89 -0
  325. package/dist/shared/memory/policy.d.ts +33 -12
  326. package/dist/shared/memory/policy.js +50 -19
  327. package/dist/shared/pty/ctrl-c.d.ts +18 -0
  328. package/dist/shared/pty/ctrl-c.js +36 -0
  329. package/dist/shared/pty/index.d.ts +1 -0
  330. package/dist/shared/pty/index.js +1 -0
  331. package/dist/shared/pty/terminal.d.ts +2 -0
  332. package/dist/shared/pty/terminal.js +21 -2
  333. package/dist/shared/vpn/kill-switch.d.ts +13 -2
  334. package/dist/shared/vpn/kill-switch.js +88 -8
  335. package/dist/shared/web/protocol.d.ts +0 -4
  336. package/dist/sync/watcher.js +1 -1
  337. package/dist/web/index.html +2 -2
  338. package/dist/web/{main-T5DMCHYV.css → main-6JF3ASB5.css} +1 -1
  339. package/dist/web/main-Z645W45E.js +219 -0
  340. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  341. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  342. package/package.json +10 -3
  343. package/sandbox/csharp/MemGov.cs +240 -38
  344. package/sandbox/csharp/PtyHost.cs +104 -15
  345. package/sandbox/csharp/SandboxTools/CpuCap.cs +50 -1
  346. package/sandbox/csharp/SandboxTools/Program.cs +1 -1
  347. package/sandbox/scripts/repair-wmi-services.ps1 +26 -0
  348. package/schemas/config.schema.json +19 -5
  349. package/schemas/sandbox-config.schema.json +7 -3
  350. package/dist/cli/commands/accounts.d.ts +0 -2
  351. package/dist/cli/commands/accounts.js +0 -96
  352. package/dist/cli/commands/data/clean.d.ts +0 -3
  353. package/dist/cli/commands/data/clean.js +0 -60
  354. package/dist/cli/commands/data/index.d.ts +0 -4
  355. package/dist/cli/commands/data/index.js +0 -62
  356. package/dist/cli/commands/maintenance/clean.d.ts +0 -2
  357. package/dist/cli/commands/maintenance/clean.js +0 -24
  358. package/dist/cli/commands/maintenance/config-share.d.ts +0 -12
  359. package/dist/cli/commands/maintenance/config-share.js +0 -80
  360. package/dist/cli/commands/projects/projects.d.ts +0 -2
  361. package/dist/cli/commands/projects/projects.js +0 -162
  362. package/dist/cli/commands/storage/contained.d.ts +0 -3
  363. package/dist/cli/commands/storage/contained.js +0 -179
  364. package/dist/cli/commands/storage/storage.d.ts +0 -8
  365. package/dist/cli/commands/storage/storage.js +0 -179
  366. package/dist/cli/menu/add-agent.d.ts +0 -47
  367. package/dist/cli/menu/add-agent.js +0 -168
  368. package/dist/cli/menu/apps.d.ts +0 -69
  369. package/dist/cli/menu/apps.js +0 -214
  370. package/dist/cli/menu/data-folder.d.ts +0 -18
  371. package/dist/cli/menu/data-folder.js +0 -99
  372. package/dist/cli/menu/share-settings.d.ts +0 -21
  373. package/dist/cli/menu/share-settings.js +0 -112
  374. package/dist/cli/menu/vpn-login.d.ts +0 -16
  375. package/dist/cli/menu/vpn-login.js +0 -74
  376. package/dist/web/main-NRRS5O6Z.js +0 -157
  377. /package/dist/cli/{commands/data/collect.d.ts → services/data-collect.d.ts} +0 -0
  378. /package/dist/cli/{commands/data/remove.d.ts → services/data-remove.d.ts} +0 -0
@@ -0,0 +1,76 @@
1
+ // The apps feature's work: the rows of a scope, an app switched on or off, your own programs saved, and the request
2
+ // page opened in this PC's browser. Writes go through ConfigFile like the settings do (comments kept, nothing written
3
+ // unless the file stays valid).
4
+ import { APPS } from '../../../shared/apps/index.js';
5
+ import { errMsg, fail } from '../../../core/util/index.js';
6
+ import { openIssuePage } from '../../../host/web/index.js';
7
+ import { implement } from '../../context.js';
8
+ import { allowedText, fieldOf, valueFromText } from '../../kernel/index.js';
9
+ import { settingsFiles } from '../settings/settings.run.js';
10
+ import { appRows, customRows, CUSTOM_KEY, INSTALL, SAVED } from './apps-rows.js';
11
+ import { listApps, requestApp, requestAppUrl, setCustomApps, toggleApp } from './apps.def.js';
12
+ export const listAppsRun = implement(listApps, (ctx, input) => {
13
+ const file = settingsFiles(ctx)[input.scope];
14
+ const own = input.scope === 'user';
15
+ const node = own ? file.schema.child('apps')?.child('custom') : undefined;
16
+ return {
17
+ scope: input.scope,
18
+ file: file.file,
19
+ exists: file.exists,
20
+ apps: appRows(file, ctx.dataPath),
21
+ custom: own ? customRows(file) : [],
22
+ ...(own ? { customValue: SAVED.custom(file) } : {}),
23
+ ...(node ? { customField: fieldOf(node, CUSTOM_KEY, 'Your own programs') } : {}),
24
+ };
25
+ });
26
+ export const toggleAppRun = implement(toggleApp, (ctx, input) => {
27
+ const file = settingsFiles(ctx)[input.scope];
28
+ const entry = APPS.find((a) => a.id === input.id);
29
+ if (!entry || (file.isProject && entry.setting))
30
+ fail('"' + input.id + '" is not an app this scope can change.', 'Pick one of the apps the Apps page lists.');
31
+ const name = entry.name;
32
+ // A setting-backed app (VS Code, Windows Terminal) is its setting; a catalogue app is one id in apps.install.
33
+ const key = entry.setting ? entry.setting.split('.') : INSTALL;
34
+ let value = input.on;
35
+ if (!entry.setting) {
36
+ const current = SAVED.install(file) ?? [];
37
+ const next = input.on
38
+ ? current.includes(entry.id)
39
+ ? current
40
+ : [...current, entry.id]
41
+ : current.filter((id) => id !== entry.id);
42
+ // Your own file keeps no empty list (back to the default); a project file always says what it chooses.
43
+ value = next.length || file.isProject ? next : undefined;
44
+ }
45
+ const outcome = file.set(key, value);
46
+ if (typeof outcome === 'object')
47
+ fail('Could not change ' + key.join('.') + ': ' + outcome.problems.join('; '), 'Nothing was written.');
48
+ const said = input.on ? name + ' is installed in every sandbox.' : name + ' is no longer installed.';
49
+ return { message: said + (outcome === 'unchanged' ? ' (it was already)' : '') };
50
+ });
51
+ export const setCustomAppsRun = implement(setCustomApps, (ctx, input) => {
52
+ if (input.scope === 'project')
53
+ fail('Your own programs are set in your own settings only.', 'Switch to All projects.');
54
+ const file = settingsFiles(ctx).user;
55
+ const node = file.schema.child('apps')?.child('custom');
56
+ if (!node)
57
+ fail('Your own programs are not a setting of this version.', 'Update sandbox, then try again.');
58
+ const value = typeof input.value === 'string' ? valueFromText(node, input.value) : input.value;
59
+ const problem = node.check(value);
60
+ if (problem !== true)
61
+ fail('That does not work for apps.custom: ' + problem, allowedText(node));
62
+ const outcome = file.set(CUSTOM_KEY, value);
63
+ if (typeof outcome === 'object')
64
+ fail('Could not change apps.custom: ' + outcome.problems.join('; '), 'Nothing was written.');
65
+ return { message: 'Your own programs are saved.' };
66
+ });
67
+ export const requestAppRun = implement(requestApp, () => {
68
+ const url = requestAppUrl();
69
+ try {
70
+ openIssuePage(url);
71
+ }
72
+ catch (e) {
73
+ fail(errMsg(e), 'Open it yourself: ' + url);
74
+ }
75
+ return { url };
76
+ });
@@ -0,0 +1,3 @@
1
+ export * from './apps.def.js';
2
+ export * from './apps.run.js';
3
+ export * from './apps-rows.js';
@@ -0,0 +1,4 @@
1
+ // The apps feature: the catalogue of apps every sandbox installs (all projects or this project) and your own programs.
2
+ export * from './apps.def.js';
3
+ export * from './apps.run.js';
4
+ export * from './apps-rows.js';
@@ -0,0 +1,154 @@
1
+ import { z } from 'zod';
2
+ import { type Page } from '../../kernel/index.js';
3
+ export declare const DATA_AREAS: readonly ["tools", "databases", "state", "logs", "data", "host"];
4
+ export type DataAreaName = (typeof DATA_AREAS)[number];
5
+ /** The heading of each area's section (the CLI's group labels). */
6
+ export declare const AREA_LABEL: Readonly<Record<DataAreaName, string>>;
7
+ declare const DataEntrySchema: z.ZodObject<{
8
+ area: z.ZodEnum<{
9
+ host: "host";
10
+ tools: "tools";
11
+ databases: "databases";
12
+ state: "state";
13
+ data: "data";
14
+ logs: "logs";
15
+ }>;
16
+ name: z.ZodString;
17
+ path: z.ZodString;
18
+ bytes: z.ZodNumber;
19
+ size: z.ZodString;
20
+ target: z.ZodNullable<z.ZodString>;
21
+ }, z.core.$strip>;
22
+ declare const DiskSchema: z.ZodObject<{
23
+ drive: z.ZodString;
24
+ totalBytes: z.ZodNumber;
25
+ freeBytes: z.ZodNumber;
26
+ usedBytes: z.ZodNumber;
27
+ holdsStorage: z.ZodBoolean;
28
+ used: z.ZodString;
29
+ usedPercent: z.ZodNumber;
30
+ free: z.ZodString;
31
+ total: z.ZodString;
32
+ }, z.core.$strip>;
33
+ export declare const DataShowSchema: z.ZodObject<{
34
+ dataPath: z.ZodString;
35
+ storageRoot: z.ZodString;
36
+ totalBytes: z.ZodNumber;
37
+ total: z.ZodString;
38
+ storageShare: z.ZodString;
39
+ areaTotals: z.ZodRecord<z.ZodString, z.ZodString>;
40
+ entries: z.ZodArray<z.ZodObject<{
41
+ area: z.ZodEnum<{
42
+ host: "host";
43
+ tools: "tools";
44
+ databases: "databases";
45
+ state: "state";
46
+ data: "data";
47
+ logs: "logs";
48
+ }>;
49
+ name: z.ZodString;
50
+ path: z.ZodString;
51
+ bytes: z.ZodNumber;
52
+ size: z.ZodString;
53
+ target: z.ZodNullable<z.ZodString>;
54
+ }, z.core.$strip>>;
55
+ disks: z.ZodArray<z.ZodObject<{
56
+ drive: z.ZodString;
57
+ totalBytes: z.ZodNumber;
58
+ freeBytes: z.ZodNumber;
59
+ usedBytes: z.ZodNumber;
60
+ holdsStorage: z.ZodBoolean;
61
+ used: z.ZodString;
62
+ usedPercent: z.ZodNumber;
63
+ free: z.ZodString;
64
+ total: z.ZodString;
65
+ }, z.core.$strip>>;
66
+ }, z.core.$strip>;
67
+ export type DataShow = z.output<typeof DataShowSchema>;
68
+ export type DataEntryRow = z.output<typeof DataEntrySchema>;
69
+ export type DataDisk = z.output<typeof DiskSchema>;
70
+ export declare const showData: import("../../kernel/define.js").QueryDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
71
+ dataPath: z.ZodString;
72
+ storageRoot: z.ZodString;
73
+ totalBytes: z.ZodNumber;
74
+ total: z.ZodString;
75
+ storageShare: z.ZodString;
76
+ areaTotals: z.ZodRecord<z.ZodString, z.ZodString>;
77
+ entries: z.ZodArray<z.ZodObject<{
78
+ area: z.ZodEnum<{
79
+ host: "host";
80
+ tools: "tools";
81
+ databases: "databases";
82
+ state: "state";
83
+ data: "data";
84
+ logs: "logs";
85
+ }>;
86
+ name: z.ZodString;
87
+ path: z.ZodString;
88
+ bytes: z.ZodNumber;
89
+ size: z.ZodString;
90
+ target: z.ZodNullable<z.ZodString>;
91
+ }, z.core.$strip>>;
92
+ disks: z.ZodArray<z.ZodObject<{
93
+ drive: z.ZodString;
94
+ totalBytes: z.ZodNumber;
95
+ freeBytes: z.ZodNumber;
96
+ usedBytes: z.ZodNumber;
97
+ holdsStorage: z.ZodBoolean;
98
+ used: z.ZodString;
99
+ usedPercent: z.ZodNumber;
100
+ free: z.ZodString;
101
+ total: z.ZodString;
102
+ }, z.core.$strip>>;
103
+ }, z.core.$strip>, "data.show">;
104
+ export declare const cleanData: import("../../kernel/define.js").OperationDef<z.ZodObject<{
105
+ targets: z.ZodDefault<z.ZodArray<z.ZodString>>;
106
+ }, z.core.$strip>, z.ZodObject<{
107
+ message: z.ZodString;
108
+ freedBytes: z.ZodNumber;
109
+ }, z.core.$strip>, "data.clean">;
110
+ export declare const pruneStorage: import("../../kernel/define.js").OperationDef<z.ZodObject<{
111
+ days: z.ZodDefault<z.ZodNumber>;
112
+ }, z.core.$strip>, z.ZodObject<{
113
+ message: z.ZodString;
114
+ removed: z.ZodBoolean;
115
+ }, z.core.$strip>, "data.prune">;
116
+ /** The data page: disks, then one section per area, the total, and clean-up. */
117
+ export declare function dataPage(o: DataShow): Page;
118
+ export declare const dataView: import("../../kernel/define.js").ViewDef<{
119
+ data: import("../../kernel/define.js").QueryDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
120
+ dataPath: z.ZodString;
121
+ storageRoot: z.ZodString;
122
+ totalBytes: z.ZodNumber;
123
+ total: z.ZodString;
124
+ storageShare: z.ZodString;
125
+ areaTotals: z.ZodRecord<z.ZodString, z.ZodString>;
126
+ entries: z.ZodArray<z.ZodObject<{
127
+ area: z.ZodEnum<{
128
+ host: "host";
129
+ tools: "tools";
130
+ databases: "databases";
131
+ state: "state";
132
+ data: "data";
133
+ logs: "logs";
134
+ }>;
135
+ name: z.ZodString;
136
+ path: z.ZodString;
137
+ bytes: z.ZodNumber;
138
+ size: z.ZodString;
139
+ target: z.ZodNullable<z.ZodString>;
140
+ }, z.core.$strip>>;
141
+ disks: z.ZodArray<z.ZodObject<{
142
+ drive: z.ZodString;
143
+ totalBytes: z.ZodNumber;
144
+ freeBytes: z.ZodNumber;
145
+ usedBytes: z.ZodNumber;
146
+ holdsStorage: z.ZodBoolean;
147
+ used: z.ZodString;
148
+ usedPercent: z.ZodNumber;
149
+ free: z.ZodString;
150
+ total: z.ZodString;
151
+ }, z.core.$strip>>;
152
+ }, z.core.$strip>, "data.show">;
153
+ }, Record<string, never>, "data">;
154
+ export {};
@@ -0,0 +1,201 @@
1
+ // The data area: what the sandbox keeps between runs (toolchains, databases, agent state, logs, what this PC keeps for
2
+ // it), deleting chosen parts of it, and the clean-up of old launch folders. Pure: the page builder is here, the work is
3
+ // in data.run.ts. Sizes come as bytes and as words (the run formats them: this file cannot import core/disk).
4
+ import { z } from 'zod';
5
+ import { action, defineOperation, defineQuery, defineView, fieldOf, SchemaNode, } from '../../kernel/index.js';
6
+ export const DATA_AREAS = ['tools', 'databases', 'state', 'logs', 'data', 'host'];
7
+ /** The heading of each area's section (the CLI's group labels). */
8
+ export const AREA_LABEL = {
9
+ tools: 'Toolchains',
10
+ databases: 'Databases',
11
+ state: 'Agent state',
12
+ logs: 'Logs',
13
+ data: 'Other',
14
+ host: 'On this PC',
15
+ };
16
+ const DataEntrySchema = z.object({
17
+ area: z.enum(DATA_AREAS).describe('Which kind of data it is'),
18
+ name: z.string().describe('The folder as listed (tools: its name; others: area/name)'),
19
+ path: z.string().describe('Its full path on this PC'),
20
+ bytes: z.number().describe('Its size in bytes (links count 0)'),
21
+ size: z.string().describe('Its size in words, e.g. 1.5 KB'),
22
+ target: z.string().nullable().describe('What sandbox data clean calls it; null when it is kept on purpose'),
23
+ });
24
+ const DiskSchema = z.object({
25
+ drive: z.string().describe('The drive, e.g. C:\\'),
26
+ totalBytes: z.number().describe('Its size in bytes'),
27
+ freeBytes: z.number().describe('Free bytes'),
28
+ usedBytes: z.number().describe('Used bytes'),
29
+ holdsStorage: z.boolean().describe('The sandbox keeps its files on this drive'),
30
+ used: z.string().describe('Used, in words'),
31
+ usedPercent: z.number().describe('Used, in percent of the size (rounded)'),
32
+ free: z.string().describe('Free, in words'),
33
+ total: z.string().describe('Size, in words'),
34
+ });
35
+ export const DataShowSchema = z.object({
36
+ dataPath: z.string().describe('The data folder (C:\\AgentData inside the sandbox)'),
37
+ storageRoot: z.string().describe('The storage folder that holds it'),
38
+ totalBytes: z.number().describe('Everything listed, in bytes'),
39
+ total: z.string().describe('Everything listed, in words'),
40
+ storageShare: z.string().describe('"<- sandbox storage (<total> of it)": the note on the storage drive'),
41
+ areaTotals: z.record(z.string(), z.string()).describe("Each area's total in words"),
42
+ entries: z.array(DataEntrySchema).describe('What is stored, by area, biggest first'),
43
+ disks: z.array(DiskSchema).describe("This PC's drives"),
44
+ });
45
+ export const showData = defineQuery({
46
+ id: 'data.show',
47
+ title: 'Stored data',
48
+ summary: 'show what is kept between sandboxes (tools, databases, logins, logs), or delete some of it',
49
+ input: z.object({}),
50
+ output: DataShowSchema,
51
+ cli: {
52
+ name: 'data',
53
+ action: 'show',
54
+ json: true,
55
+ // The --json shape `sandbox data` has always printed.
56
+ shapeJson: (o) => ({
57
+ dataPath: o.dataPath,
58
+ storageRoot: o.storageRoot,
59
+ totalBytes: o.totalBytes,
60
+ entries: o.entries.map(({ area, name, path, bytes }) => ({ area, name, path, bytes })),
61
+ disks: o.disks.map(({ drive, totalBytes, freeBytes, usedBytes, holdsStorage }) => ({
62
+ drive,
63
+ totalBytes,
64
+ freeBytes,
65
+ usedBytes,
66
+ holdsStorage,
67
+ })),
68
+ }),
69
+ },
70
+ });
71
+ const MessageSchema = z.object({ message: z.string().describe('What happened') });
72
+ export const cleanData = defineOperation({
73
+ id: 'data.clean',
74
+ title: 'Delete stored data…',
75
+ summary: 'delete chosen parts of what is kept between sandboxes',
76
+ input: z.object({
77
+ targets: z.array(z.string()).default([]).describe('what to clean, e.g. tools/go databases logs'),
78
+ }),
79
+ output: MessageSchema.extend({
80
+ freedBytes: z.number().describe('Bytes freed (0 when nothing was removed)'),
81
+ }),
82
+ danger: true,
83
+ text: (o) => o.message,
84
+ next: (o) => (o.freedBytes > 0 ? 'sandbox data (see what is left)' : undefined),
85
+ cli: { name: 'data', action: 'clean', positional: ['targets'] },
86
+ });
87
+ const PruneInputSchema = z.object({
88
+ days: z.number().int().min(1).default(7).describe('launch folders older than this many days'),
89
+ });
90
+ export const pruneStorage = defineOperation({
91
+ id: 'data.prune',
92
+ title: 'Clean up…',
93
+ summary: 'delete old launch folders, logs and leftovers',
94
+ input: PruneInputSchema,
95
+ output: MessageSchema.extend({ removed: z.boolean().describe('Something was deleted') }),
96
+ text: (o) => o.message,
97
+ next: (o) => (o.removed ? 'sandbox data (see what else is saved, and clean it)' : undefined),
98
+ cli: {
99
+ name: 'clean',
100
+ group: 'Data',
101
+ flags: { days: { flag: '--days', value: 'n' } },
102
+ yes: 'do not ask before deleting',
103
+ },
104
+ });
105
+ const DAYS_FIELD = fieldOf(new SchemaNode(PruneInputSchema).child('days'), ['days']);
106
+ /** The data page: disks, then one section per area, the total, and clean-up. */
107
+ export function dataPage(o) {
108
+ const disks = {
109
+ id: 'disks',
110
+ title: 'Disks',
111
+ columns: [
112
+ { key: 'drive', label: 'DRIVE' },
113
+ { key: 'used', label: 'USED' },
114
+ { key: 'free', label: 'FREE' },
115
+ { key: 'size', label: 'SIZE' },
116
+ { key: 'note', label: '' },
117
+ ],
118
+ // The web shows each drive as a row (a table with the storage note does not fit a phone); the CLI keeps the table.
119
+ columnsOn: 'cli',
120
+ items: o.disks.map((d) => ({
121
+ id: 'disk:' + d.drive,
122
+ label: d.drive,
123
+ hint: d.used + ' used · ' + d.free + ' free of ' + d.total, // the menu's wording
124
+ ...(d.holdsStorage ? { description: 'The sandbox keeps its files on this drive.' } : {}),
125
+ cells: {
126
+ drive: d.drive,
127
+ used: d.used + ' (' + d.usedPercent + '%)',
128
+ free: d.free,
129
+ size: d.total,
130
+ note: d.holdsStorage ? o.storageShare : '',
131
+ },
132
+ })),
133
+ notes: [{ text: 'Persistent data for the sandbox: ' + o.dataPath + ' (C:\\AgentData inside)' }],
134
+ };
135
+ const areas = DATA_AREAS.flatMap((area) => {
136
+ const rows = o.entries.filter((e) => e.area === area);
137
+ if (!rows.length)
138
+ return [];
139
+ return [
140
+ {
141
+ id: 'area:' + area,
142
+ title: AREA_LABEL[area],
143
+ summary: o.areaTotals[area] ?? '',
144
+ columns: [
145
+ { key: 'name', label: '' },
146
+ { key: 'size', label: '' },
147
+ { key: 'path', label: '' },
148
+ ],
149
+ columnsOn: 'cli',
150
+ items: rows.map((e) => ({
151
+ id: 'entry:' + e.name,
152
+ label: e.name,
153
+ hint: e.size,
154
+ ...(e.target
155
+ ? { keys: 'x deletes it.' }
156
+ : { description: 'Kept on this PC on purpose; it is not deleted here.' }),
157
+ details: ['Folder ' + e.path],
158
+ cells: { name: ' ' + e.name, size: e.size, path: e.path },
159
+ actions: e.target
160
+ ? [action(cleanData, { targets: [e.target] }, { label: 'Delete', key: 'x', verb: 'delete' })]
161
+ : [],
162
+ })),
163
+ },
164
+ ];
165
+ });
166
+ const total = {
167
+ id: 'total',
168
+ facts: [{ id: 'total', label: 'Total', value: o.total }],
169
+ notes: [
170
+ ...(o.entries.length
171
+ ? []
172
+ : [{ text: 'Nothing stored yet. Toolchains, databases and agent logins appear here after the first start.' }]),
173
+ {
174
+ text: 'Free space with: sandbox data clean <target...> (e.g. tools/go, databases/postgres-18, logs, launches)',
175
+ tone: 'muted',
176
+ only: 'cli',
177
+ },
178
+ ],
179
+ };
180
+ const clean = {
181
+ id: 'clean',
182
+ title: 'Clean up',
183
+ actions: [
184
+ action(pruneStorage, {}, {
185
+ label: 'Clean up…',
186
+ verb: 'choose what',
187
+ description: 'Delete caches, old sandboxes and other leftovers (the clean command, with its options).',
188
+ fields: [DAYS_FIELD],
189
+ }),
190
+ ],
191
+ };
192
+ return { title: 'Data', sections: [disks, ...areas, total, clean] };
193
+ }
194
+ export const dataView = defineView({
195
+ id: 'data',
196
+ title: 'Data',
197
+ summary: 'What the sandbox keeps between runs, and deleting parts of it.',
198
+ queries: { data: showData },
199
+ operations: [cleanData, pruneStorage],
200
+ build: ({ data }) => dataPage(data),
201
+ });
@@ -0,0 +1,46 @@
1
+ export declare const showDataRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
2
+ dataPath: import("zod").ZodString;
3
+ storageRoot: import("zod").ZodString;
4
+ totalBytes: import("zod").ZodNumber;
5
+ total: import("zod").ZodString;
6
+ storageShare: import("zod").ZodString;
7
+ areaTotals: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>;
8
+ entries: import("zod").ZodArray<import("zod").ZodObject<{
9
+ area: import("zod").ZodEnum<{
10
+ host: "host";
11
+ tools: "tools";
12
+ databases: "databases";
13
+ state: "state";
14
+ data: "data";
15
+ logs: "logs";
16
+ }>;
17
+ name: import("zod").ZodString;
18
+ path: import("zod").ZodString;
19
+ bytes: import("zod").ZodNumber;
20
+ size: import("zod").ZodString;
21
+ target: import("zod").ZodNullable<import("zod").ZodString>;
22
+ }, import("zod/v4/core").$strip>>;
23
+ disks: import("zod").ZodArray<import("zod").ZodObject<{
24
+ drive: import("zod").ZodString;
25
+ totalBytes: import("zod").ZodNumber;
26
+ freeBytes: import("zod").ZodNumber;
27
+ usedBytes: import("zod").ZodNumber;
28
+ holdsStorage: import("zod").ZodBoolean;
29
+ used: import("zod").ZodString;
30
+ usedPercent: import("zod").ZodNumber;
31
+ free: import("zod").ZodString;
32
+ total: import("zod").ZodString;
33
+ }, import("zod/v4/core").$strip>>;
34
+ }, import("zod/v4/core").$strip>, "data.show">, import("../../../cli/commands/context.js").Context>;
35
+ export declare const cleanDataRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
36
+ targets: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
37
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
38
+ message: import("zod").ZodString;
39
+ freedBytes: import("zod").ZodNumber;
40
+ }, import("zod/v4/core").$strip>, "data.clean">, import("../../../cli/commands/context.js").Context>;
41
+ export declare const pruneStorageRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
42
+ days: import("zod").ZodDefault<import("zod").ZodNumber>;
43
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
44
+ message: import("zod").ZodString;
45
+ removed: import("zod").ZodBoolean;
46
+ }, import("zod/v4/core").$strip>, "data.prune">, import("../../../cli/commands/context.js").Context>;
@@ -0,0 +1,141 @@
1
+ // The data area's work: measuring what is kept, deleting chosen parts of it (DataService: never follows links, refuses
2
+ // while a sandbox runs) and the clean-up of old launch folders, logs and leftovers. Talks only through io.
3
+ import { humanBytes } from '../../../core/disk.js';
4
+ import { fail } from '../../../core/util/index.js';
5
+ import { cleanTargetOf, DataService } from '../../../cli/services/index.js';
6
+ import { describePrune, pruneStorage as prune } from '../../../host/storage/index.js';
7
+ import { isSandboxRunning } from '../../../host/sandbox/index.js';
8
+ import { RunDir } from '../../../shared/channel/index.js';
9
+ import { implement } from '../../context.js';
10
+ import { cancelled } from '../../kernel/index.js';
11
+ import { cleanData, DATA_AREAS, pruneStorage, showData } from './data.def.js';
12
+ const MEASURING = 'Measuring the saved data (big folders take a moment)';
13
+ const NOTHING_CHOSEN = 'Nothing chosen, nothing removed.';
14
+ /** The page's numbers, in bytes and in words (the definition cannot format them). */
15
+ function showOf(report) {
16
+ const total = report.totalBytes;
17
+ const areaTotals = {};
18
+ for (const area of DATA_AREAS) {
19
+ const sum = report.entries.filter((e) => e.area === area).reduce((n, e) => n + e.bytes, 0);
20
+ areaTotals[area] = humanBytes(sum);
21
+ }
22
+ return {
23
+ dataPath: report.dataPath,
24
+ storageRoot: report.storageRoot,
25
+ totalBytes: total,
26
+ total: humanBytes(total),
27
+ storageShare: '<- sandbox storage (' + humanBytes(total) + ' of it)',
28
+ areaTotals,
29
+ entries: report.entries.map((e) => ({
30
+ area: e.area,
31
+ name: e.name,
32
+ path: e.path,
33
+ bytes: e.bytes,
34
+ size: humanBytes(e.bytes),
35
+ target: cleanTargetOf(e),
36
+ })),
37
+ disks: report.disks.map((d) => ({
38
+ drive: d.drive,
39
+ totalBytes: d.totalBytes,
40
+ freeBytes: d.freeBytes,
41
+ usedBytes: d.usedBytes,
42
+ holdsStorage: d.holdsStorage,
43
+ used: humanBytes(d.usedBytes),
44
+ usedPercent: Math.round((d.usedBytes / d.totalBytes) * 100),
45
+ free: humanBytes(d.freeBytes),
46
+ total: humanBytes(d.totalBytes),
47
+ })),
48
+ };
49
+ }
50
+ /** Rows as aligned columns, as the command line's tables print them (the last column is not padded). */
51
+ function alignedLines(rows) {
52
+ const width = (i) => Math.max(0, ...rows.map((r) => (r[i] ?? '').length));
53
+ return rows.map((row) => row.map((cell, i) => (i === row.length - 1 ? cell : cell.padEnd(width(i) + 2))).join(''));
54
+ }
55
+ /** No target named: what can be cleaned, with sizes, to tick from. Undefined when nothing can be. */
56
+ async function pickTargets(service, io) {
57
+ io.progress(MEASURING);
58
+ const choices = service.entries().flatMap((e) => {
59
+ const target = cleanTargetOf(e);
60
+ return target ? [{ value: target, label: target.padEnd(28) + humanBytes(e.bytes) }] : [];
61
+ });
62
+ if (!choices.length)
63
+ return undefined;
64
+ return io.checklist({
65
+ title: 'What do you want to delete? (space ticks, enter confirms)',
66
+ choices,
67
+ noTerminal: {
68
+ message: 'Which data should be cleaned?',
69
+ fix: 'Name them: sandbox data clean logs tools/go (what exists: sandbox data)',
70
+ },
71
+ });
72
+ }
73
+ export const showDataRun = implement(showData, (ctx) => {
74
+ return showOf(new DataService(ctx).report());
75
+ });
76
+ export const cleanDataRun = implement(cleanData, async (ctx, input, io) => {
77
+ const service = new DataService(ctx);
78
+ let inputs = input.targets;
79
+ if (!inputs.length) {
80
+ const chosen = await pickTargets(service, io);
81
+ if (!chosen?.length)
82
+ return { message: NOTHING_CHOSEN, freedBytes: 0 };
83
+ inputs = chosen;
84
+ }
85
+ const plan = service.plan(inputs);
86
+ if (!plan.present.length)
87
+ return {
88
+ message: 'Nothing to remove: ' + plan.targets.map((t) => t.target).join(', ') + ' do(es) not exist.',
89
+ freedBytes: 0,
90
+ };
91
+ for (const line of alignedLines(plan.present.map((t) => [' ' + t.target, humanBytes(t.bytes), t.path])))
92
+ io.log(line);
93
+ for (const t of plan.present)
94
+ if (t.warning)
95
+ io.log('Warning: ' + t.target + ' ' + t.warning + '.', 'warn');
96
+ const names = plan.present.map((t) => t.target).join(', ');
97
+ const confirmed = plan.present.some((t) => t.target === 'all')
98
+ ? await io.confirm({
99
+ title: 'This cannot be undone; the next sandbox starts from scratch and reinstalls everything.',
100
+ typed: 'all',
101
+ danger: true,
102
+ noTerminal: { message: 'Nothing removed.', fix: 'Add --yes to delete without asking.' },
103
+ })
104
+ : await io.confirm({
105
+ title: 'Delete ' + names + ' (' + humanBytes(plan.totalBytes) + ')? This cannot be undone.',
106
+ yes: 'Delete',
107
+ danger: true,
108
+ noTerminal: { message: 'Cannot ask here (no terminal).', fix: 'Add --yes to delete without asking.' },
109
+ });
110
+ if (!confirmed)
111
+ cancelled('Nothing removed.');
112
+ const outcome = service.clean(plan);
113
+ if (outcome.failed.length)
114
+ fail('Could not remove everything: ' + outcome.failed.join('; '), 'Close programs using those folders and run the same command again.');
115
+ return {
116
+ message: 'Removed ' +
117
+ names +
118
+ ' and freed ' +
119
+ humanBytes(outcome.freedBytes) +
120
+ (outcome.touchedData ? '; the next sandbox reinstalls what it needs.' : '.'),
121
+ freedBytes: outcome.freedBytes,
122
+ };
123
+ });
124
+ export const pruneStorageRun = implement(pruneStorage, async (ctx, input, io) => {
125
+ const running = isSandboxRunning() ? new RunDir(ctx.dataPath).readSandboxStatus()?.launchId : undefined;
126
+ const options = { launchDays: input.days, keep: running ? [running] : [] };
127
+ const found = prune(ctx.storageRoot, { ...options, dryRun: true });
128
+ if (found.launches + found.logs + found.leftovers === 0)
129
+ return { message: 'Nothing to clean.', removed: false };
130
+ io.log('Can be removed: ' + describePrune(found).replace(' removed', '') + '.');
131
+ const confirmed = await io.confirm({
132
+ title: 'Delete them?',
133
+ yes: 'Delete',
134
+ danger: true,
135
+ noTerminal: { message: 'Cannot ask here (no terminal).', fix: 'Add --yes to delete without asking.' },
136
+ });
137
+ if (!confirmed)
138
+ cancelled('Nothing removed.');
139
+ const removed = describePrune(prune(ctx.storageRoot, options)).replace(' removed', '');
140
+ return { message: 'Removed ' + removed + '.', removed: true };
141
+ });
@@ -0,0 +1,2 @@
1
+ export * from './data.def.js';
2
+ export * from './data.run.js';
@@ -0,0 +1,3 @@
1
+ // The data area: what the sandbox keeps between runs, deleting parts of it, and the clean-up.
2
+ export * from './data.def.js';
3
+ export * from './data.run.js';