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
@@ -464,10 +464,10 @@ declare const COMMAND_LIST: readonly [{
464
464
  readonly name: "engine";
465
465
  readonly summary: "(beta) what runs your sandbox (Windows Sandbox or HCS) and what each engine can do on this PC";
466
466
  readonly group: "Health";
467
- readonly examples: readonly ["sandbox engine the engine in use and what each can do", "sandbox engine check hcs what this PC lacks for the HCS engine, and the commands that would fix it"];
467
+ readonly examples: readonly ["sandbox engine the engine in use and what each can do", "sandbox engine check hcs what this PC lacks for the HCS engine, and the commands that would fix it", "sandbox engine leftovers HCS systems a crashed command left running", "sandbox engine clean stop them (memory is freed; nothing is deleted)"];
468
468
  readonly args: readonly [{
469
469
  readonly name: "action";
470
- readonly description: "show or check";
470
+ readonly description: "show, check, leftovers or clean";
471
471
  readonly required: false;
472
472
  readonly choices: readonly ["show", "check"];
473
473
  }, {
@@ -477,20 +477,7 @@ declare const COMMAND_LIST: readonly [{
477
477
  readonly choices: readonly ["windows-sandbox", "hcs"];
478
478
  readonly when: "check";
479
479
  }];
480
- readonly options: readonly [];
481
- readonly json: true;
482
- }, {
483
- readonly name: "clean";
484
- readonly summary: "delete old launch folders, logs and leftovers";
485
- readonly group: "Data";
486
- readonly args: readonly [];
487
480
  readonly options: readonly [{
488
- readonly flag: "--days";
489
- readonly type: "number";
490
- readonly value: "n";
491
- readonly description: "launch folders older than this many days";
492
- readonly default: 7;
493
- }, {
494
481
  flag: string;
495
482
  type: "string" | "number" | "boolean" | "list";
496
483
  description: string;
@@ -505,6 +492,7 @@ declare const COMMAND_LIST: readonly [{
505
492
  group?: string | undefined;
506
493
  shownAs?: string | undefined;
507
494
  }];
495
+ readonly json: true;
508
496
  }, {
509
497
  readonly name: "sync";
510
498
  readonly summary: "copy conversation history back to this PC now";
@@ -627,144 +615,6 @@ declare const COMMAND_LIST: readonly [{
627
615
  shownAs?: string | undefined;
628
616
  }];
629
617
  readonly json: true;
630
- }, {
631
- readonly name: "migrate";
632
- readonly summary: "bring your saved settings up to date with this version";
633
- readonly group: "Health";
634
- readonly args: readonly [];
635
- readonly options: readonly [{
636
- flag: string;
637
- type: "string" | "number" | "boolean" | "list";
638
- description: string;
639
- short?: string | undefined;
640
- value?: string | undefined;
641
- label?: string | undefined;
642
- default?: string | number | undefined;
643
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
644
- advanced?: boolean | undefined;
645
- when?: string | undefined;
646
- noMenu?: boolean | undefined;
647
- group?: string | undefined;
648
- shownAs?: string | undefined;
649
- }, {
650
- flag: string;
651
- type: "string" | "number" | "boolean" | "list";
652
- description: string;
653
- short?: string | undefined;
654
- value?: string | undefined;
655
- label?: string | undefined;
656
- default?: string | number | undefined;
657
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
658
- advanced?: boolean | undefined;
659
- when?: string | undefined;
660
- noMenu?: boolean | undefined;
661
- group?: string | undefined;
662
- shownAs?: string | undefined;
663
- }, {
664
- flag: string;
665
- type: "string" | "number" | "boolean" | "list";
666
- description: string;
667
- short?: string | undefined;
668
- value?: string | undefined;
669
- label?: string | undefined;
670
- default?: string | number | undefined;
671
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
672
- advanced?: boolean | undefined;
673
- when?: string | undefined;
674
- noMenu?: boolean | undefined;
675
- group?: string | undefined;
676
- shownAs?: string | undefined;
677
- }];
678
- }, {
679
- readonly name: "update";
680
- readonly summary: "install the newest version, or check, go back, or switch automatic updates";
681
- readonly group: "Health";
682
- readonly args: readonly [];
683
- readonly options: readonly [{
684
- flag: string;
685
- type: "string" | "number" | "boolean" | "list";
686
- description: string;
687
- short?: string | undefined;
688
- value?: string | undefined;
689
- label?: string | undefined;
690
- default?: string | number | undefined;
691
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
692
- advanced?: boolean | undefined;
693
- when?: string | undefined;
694
- noMenu?: boolean | undefined;
695
- group?: string | undefined;
696
- shownAs?: string | undefined;
697
- }, {
698
- flag: string;
699
- type: "string" | "number" | "boolean" | "list";
700
- description: string;
701
- short?: string | undefined;
702
- value?: string | undefined;
703
- label?: string | undefined;
704
- default?: string | number | undefined;
705
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
706
- advanced?: boolean | undefined;
707
- when?: string | undefined;
708
- noMenu?: boolean | undefined;
709
- group?: string | undefined;
710
- shownAs?: string | undefined;
711
- }, {
712
- flag: string;
713
- type: "string" | "number" | "boolean" | "list";
714
- description: string;
715
- short?: string | undefined;
716
- value?: string | undefined;
717
- label?: string | undefined;
718
- default?: string | number | undefined;
719
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
720
- advanced?: boolean | undefined;
721
- when?: string | undefined;
722
- noMenu?: boolean | undefined;
723
- group?: string | undefined;
724
- shownAs?: string | undefined;
725
- }, {
726
- flag: string;
727
- type: "string" | "number" | "boolean" | "list";
728
- description: string;
729
- short?: string | undefined;
730
- value?: string | undefined;
731
- label?: string | undefined;
732
- default?: string | number | undefined;
733
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
734
- advanced?: boolean | undefined;
735
- when?: string | undefined;
736
- noMenu?: boolean | undefined;
737
- group?: string | undefined;
738
- shownAs?: string | undefined;
739
- }, {
740
- flag: string;
741
- type: "string" | "number" | "boolean" | "list";
742
- description: string;
743
- short?: string | undefined;
744
- value?: string | undefined;
745
- label?: string | undefined;
746
- default?: string | number | undefined;
747
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
748
- advanced?: boolean | undefined;
749
- when?: string | undefined;
750
- noMenu?: boolean | undefined;
751
- group?: string | undefined;
752
- shownAs?: string | undefined;
753
- }, {
754
- flag: string;
755
- type: "string" | "number" | "boolean" | "list";
756
- description: string;
757
- short?: string | undefined;
758
- value?: string | undefined;
759
- label?: string | undefined;
760
- default?: string | number | undefined;
761
- choices?: string[] | "harnesses" | "sessions" | "accounts" | undefined;
762
- advanced?: boolean | undefined;
763
- when?: string | undefined;
764
- noMenu?: boolean | undefined;
765
- group?: string | undefined;
766
- shownAs?: string | undefined;
767
- }];
768
618
  }, {
769
619
  readonly name: "repair";
770
620
  readonly summary: "find and fix problems (install, data folder, settings, stale state, half-installed tools)";
@@ -887,6 +737,19 @@ declare const COMMAND_LIST: readonly [{
887
737
  readonly options: readonly [];
888
738
  readonly json: true;
889
739
  readonly examples: readonly ["sandbox vpn login", "sandbox vpn status"];
740
+ }, {
741
+ readonly name: "github";
742
+ readonly summary: "a GitHub token for sandboxes: save it (best a fine-grained one), see whether they get it";
743
+ readonly group: "Advanced";
744
+ readonly args: readonly [{
745
+ readonly name: "action";
746
+ readonly description: "status, login or logout";
747
+ readonly required: false;
748
+ readonly choices: readonly ["status", "login", "logout"];
749
+ }];
750
+ readonly options: readonly [];
751
+ readonly json: true;
752
+ readonly examples: readonly ["sandbox github login", "sandbox github status"];
890
753
  }, {
891
754
  readonly name: "host-claude";
892
755
  readonly summary: "run Claude on this PC, NOT sandboxed, with its own profile (same as: sandbox host claude)";
@@ -369,9 +369,11 @@ const COMMAND_LIST = [
369
369
  examples: [
370
370
  'sandbox engine the engine in use and what each can do',
371
371
  'sandbox engine check hcs what this PC lacks for the HCS engine, and the commands that would fix it',
372
+ 'sandbox engine leftovers HCS systems a crashed command left running',
373
+ 'sandbox engine clean stop them (memory is freed; nothing is deleted)',
372
374
  ],
373
375
  args: [
374
- { name: 'action', description: 'show or check', required: false, choices: ['show', 'check'] },
376
+ { name: 'action', description: 'show, check, leftovers or clean', required: false, choices: ['show', 'check'] },
375
377
  {
376
378
  name: 'engine',
377
379
  description: 'the engine to check',
@@ -380,25 +382,9 @@ const COMMAND_LIST = [
380
382
  when: 'check',
381
383
  },
382
384
  ],
383
- options: [],
385
+ options: [bool('--yes', '(clean) do not ask before stopping', { short: '-y', when: 'clean', noMenu: true })],
384
386
  json,
385
387
  },
386
- {
387
- name: 'clean',
388
- summary: 'delete old launch folders, logs and leftovers',
389
- group: 'Data',
390
- args: [],
391
- options: [
392
- {
393
- flag: '--days',
394
- type: 'number',
395
- value: 'n',
396
- description: 'launch folders older than this many days',
397
- default: 7,
398
- },
399
- bool('--yes', 'do not ask before deleting', { short: '-y', noMenu: true }),
400
- ],
401
- },
402
388
  { name: 'sync', summary: 'copy conversation history back to this PC now', group: 'Data', args: [], options: [] },
403
389
  {
404
390
  name: 'audit',
@@ -442,38 +428,6 @@ const COMMAND_LIST = [
442
428
  ],
443
429
  json: true,
444
430
  },
445
- {
446
- name: 'migrate',
447
- summary: 'bring your saved settings up to date with this version',
448
- group: 'Health',
449
- args: [],
450
- options: [
451
- bool('--dry-run', 'only list what would change'),
452
- text('--restore', 'backup', 'put back the files saved before an update (a folder under <storage>\\backups)', {
453
- advanced: true,
454
- }),
455
- bool('--yes', '(--restore) do not ask first', { short: '-y', noMenu: true }),
456
- ],
457
- },
458
- {
459
- name: 'update',
460
- summary: 'install the newest version, or check, go back, or switch automatic updates',
461
- group: 'Health',
462
- args: [],
463
- options: [
464
- bool('--check', 'only look whether a newer version exists'),
465
- bool('--rollback', 'go back to the version before the last update'),
466
- bool('--yes', '(--rollback) do not ask first', { short: '-y', noMenu: true }),
467
- text('--auto', 'on|off', 'install new versions by themselves (for everyone on this PC: needs an admin terminal)', {
468
- choices: ['on', 'off'],
469
- }),
470
- bool('--unattended', 'used by automatic updates: no questions, short output', { noMenu: true, advanced: true }),
471
- text('--feed', 'folder', 'take the release from this folder (a feed.json and the package) instead of GitHub', {
472
- noMenu: true,
473
- advanced: true,
474
- }),
475
- ],
476
- },
477
431
  {
478
432
  name: 'repair',
479
433
  summary: 'find and fix problems (install, data folder, settings, stale state, half-installed tools)',
@@ -554,6 +508,22 @@ const COMMAND_LIST = [
554
508
  json: true,
555
509
  examples: ['sandbox vpn login', 'sandbox vpn status'],
556
510
  },
511
+ {
512
+ name: 'github',
513
+ summary: 'a GitHub token for sandboxes: save it (best a fine-grained one), see whether they get it',
514
+ group: 'Advanced',
515
+ args: [
516
+ {
517
+ name: 'action',
518
+ description: 'status, login or logout',
519
+ required: false,
520
+ choices: ['status', 'login', 'logout'],
521
+ },
522
+ ],
523
+ options: [],
524
+ json: true,
525
+ examples: ['sandbox github login', 'sandbox github status'],
526
+ },
557
527
  {
558
528
  name: 'host-claude',
559
529
  summary: 'run Claude on this PC, NOT sandboxed, with its own profile (same as: sandbox host claude)',
@@ -9,8 +9,7 @@ import { SandboxChannel } from '../../host/channel/index.js';
9
9
  import { isSandboxRunning } from '../../host/sandbox/index.js';
10
10
  import { moveProblem } from '../../host/storage/index.js';
11
11
  import { splitArgs } from '../args.js';
12
- import { cleanTargetOf } from '../commands/data/collect.js';
13
- import { AccountsService, DataService, ProjectsService } from '../services/index.js';
12
+ import { AccountsService, cleanTargetOf, DataService, ProjectsService } from '../services/index.js';
14
13
  import { commandLine } from '../history.js';
15
14
  import { askedWhen } from '../manifest.js';
16
15
  import { Text, Theme } from '../tui/index.js';
@@ -17,13 +17,13 @@ export declare class MenuOperations {
17
17
  private readonly ctx;
18
18
  constructor(app: App, ctx: Context);
19
19
  /** Does what an action of a page says: follows a link, or asks for its fields and runs its operation. */
20
- perform(action: Action, where: Where, busy?: ShowBusy): Promise<Performed>;
20
+ perform(action: Action, where: Where, busy?: ShowBusy, onOutput?: (output: unknown) => void): Promise<Performed>;
21
21
  /** The values of an action's fields, from the editors that fit them (undefined: one was backed out of). */
22
22
  private fields;
23
23
  /**
24
24
  * Runs a definition with this input and returns the notice to show: its text (✓), the problem and its fix (✘), or
25
25
  * undefined when a question was declined (nothing changed, nothing to say).
26
26
  */
27
- run(def: AnyDefinition, input: unknown, where: Where, busy?: ShowBusy): Promise<string | undefined>;
27
+ run(def: AnyDefinition, input: unknown, where: Where, busy?: ShowBusy, onOutput?: (output: unknown) => void): Promise<string | undefined>;
28
28
  }
29
29
  export {};
@@ -72,7 +72,7 @@ export class MenuOperations {
72
72
  this.ctx = ctx;
73
73
  }
74
74
  /** Does what an action of a page says: follows a link, or asks for its fields and runs its operation. */
75
- async perform(action, where, busy) {
75
+ async perform(action, where, busy, onOutput) {
76
76
  if (action.kind === 'link')
77
77
  return follow(action.target);
78
78
  const def = operationById(action.op);
@@ -81,7 +81,7 @@ export class MenuOperations {
81
81
  const answers = await this.fields(action, def, where);
82
82
  if (!answers)
83
83
  return {};
84
- return { reload: true, notice: await this.run(def, { ...action.input, ...answers }, where, busy) };
84
+ return { reload: true, notice: await this.run(def, { ...action.input, ...answers }, where, busy, onOutput) };
85
85
  }
86
86
  /** The values of an action's fields, from the editors that fit them (undefined: one was backed out of). */
87
87
  async fields(action, def, where) {
@@ -102,7 +102,7 @@ export class MenuOperations {
102
102
  * Runs a definition with this input and returns the notice to show: its text (✓), the problem and its fix (✘), or
103
103
  * undefined when a question was declined (nothing changed, nothing to say).
104
104
  */
105
- async run(def, input, where, busy = () => undefined) {
105
+ async run(def, input, where, busy = () => undefined, onOutput) {
106
106
  const said = [];
107
107
  const asker = async (q) => (await ask(this.app, where, q, said.splice(0)));
108
108
  const io = ioFromAsker(asker, {
@@ -111,7 +111,9 @@ export class MenuOperations {
111
111
  });
112
112
  try {
113
113
  const output = await runDefinition(def.id, this.ctx, input, io);
114
- const text = def.text?.(output);
114
+ onOutput?.(output);
115
+ // The notice is one line: an operation that says several lines (accounts use) runs them together.
116
+ const text = def.text?.(output)?.replace(/\n+/g, ' ');
115
117
  return text ? Theme.ok(Theme.glyph.ok + ' ' + text) : undefined;
116
118
  }
117
119
  catch (e) {
@@ -81,7 +81,7 @@ export class Menu {
81
81
  new AgentsPage(app, ctx, files.user, draft),
82
82
  new SessionsPage(app, ctx),
83
83
  new SandboxPage(app, ctx),
84
- new AppsPage(app, files, draft, ctx.dataPath),
84
+ new AppsPage(app, ctx, files, draft),
85
85
  new SettingsPage(app, files, draft, ctx),
86
86
  new AccountsPage(app, ctx),
87
87
  new MaintenancePage(app, ctx),
@@ -1,29 +1,17 @@
1
- import type { AccountRow } from '../../../host/profile/index.js';
1
+ import { type AccountsList } from '../../../app/features/accounts/index.js';
2
2
  import type { Context } from '../../commands/context.js';
3
- import { type AgentAccounts } from '../../services/index.js';
4
- import { type App, type ListOptions, type ListResult } from '../../tui/index.js';
3
+ import type { App, ListOptions, ListResult } from '../../tui/index.js';
5
4
  import { ListPage, type Outcome } from './list-page.js';
6
- export interface AccountsModel {
7
- readonly agents: readonly AgentAccounts[];
8
- /** Saved logins by agent name. */
9
- readonly rows: Readonly<Record<string, readonly AccountRow[]>>;
10
- }
5
+ export type AccountsModel = AccountsList;
11
6
  /** The list for the accounts tab. Pure. */
12
7
  export declare function accountsOptions(m: AccountsModel): ListOptions<string>;
13
8
  export declare class AccountsPage extends ListPage<string> {
9
+ private readonly ctx;
14
10
  readonly label = "Accounts";
15
11
  private model;
16
- private readonly service;
12
+ private readonly operations;
17
13
  constructor(app: App, ctx: Context);
18
14
  protected load(): Promise<void>;
19
15
  protected options(): ListOptions<string>;
20
- /** The agent of the open category, and the login name of an item value ("agent:name"). */
21
- private agentNow;
22
- private static nameOf;
23
16
  protected act(result: ListResult<string>): Promise<Outcome<string>>;
24
- private askName;
25
- private save;
26
- private rename;
27
- private use;
28
- private remove;
29
17
  }
@@ -1,14 +1,17 @@
1
- // Section 6: saved logins for every agent. Agents on the left (each with its logins), actions on the right: save the
2
- // sandbox's login or this PC's, use one, make one the default, rename, remove.
3
- import { errMsg, safeText } from '../../../core/util/index.js';
4
- import { AccountsService } from '../../services/index.js';
5
- import { Theme } from '../../tui/index.js';
1
+ // Section 6: the saved logins of every agent, as the accounts view shows them (src/app/features/accounts). One category
2
+ // per agent: its save rows and its logins. Keys and Enter act on the open agent only; what they do is the operation's.
3
+ import { agentPage, listAccounts } from '../../../app/features/accounts/index.js';
4
+ import { readQuery } from '../../../app/registry.js';
5
+ import { MenuOperations } from '../io-menu.js';
6
+ import { menuView } from '../render-view.js';
6
7
  import { ListPage } from './list-page.js';
7
- const NAME = /^[A-Za-z0-9_-]{1,40}$/;
8
- const SAVE_SANDBOX = '@save-sandbox';
9
- const SAVE_PC = '@save-pc';
10
- /** A saved login (not a "save a login" row or a note). */
11
- const isLogin = (id) => !id.startsWith('@') && !id.startsWith('info:');
8
+ /** The menu's rows, keys and Enter labels of one agent's category. */
9
+ function viewOf(m, category) {
10
+ const agent = m.agents.find((a) => a.name === category);
11
+ return agent
12
+ ? menuView(agentPage(agent), { category: agent.name, refresh: false })
13
+ : menuView({ title: 'Accounts', sections: [] }, { refresh: false });
14
+ }
12
15
  /** The list for the accounts tab. Pure. */
13
16
  export function accountsOptions(m) {
14
17
  return {
@@ -21,179 +24,34 @@ export function accountsOptions(m) {
21
24
  ? 'Saved ' + a.name + ' logins.'
22
25
  : "This agent's login is not kept between sandboxes: it cannot be pointed at a folder we control.",
23
26
  })),
24
- items: m.agents.flatMap((a) => {
25
- const rows = m.rows[a.name] ?? [];
26
- const save = [
27
- {
28
- value: SAVE_SANDBOX,
29
- label: "+ Save the sandbox's login…",
30
- category: a.name,
31
- section: 'Save a login',
32
- description: 'Saves the ' + a.name + ' login you signed in with inside the sandbox, under a name you choose.',
33
- },
34
- ...(a.canSavePc
35
- ? [
36
- {
37
- value: SAVE_PC,
38
- label: "+ Save this PC's login…",
39
- category: a.name,
40
- section: 'Save a login',
41
- description: 'Saves the ' + a.name + ' login of this PC, under a name you choose.',
42
- },
43
- ]
44
- : []),
45
- ];
46
- if (!a.kept)
47
- return [
48
- {
49
- value: 'info:' + a.name,
50
- label: Theme.muted("This agent's login is not kept between sandboxes"),
51
- category: a.name,
52
- description: 'Sign in again in each new sandbox, or use an API key in the agent’s environment.',
53
- },
54
- ];
55
- return [
56
- ...save,
57
- ...rows.map((r) => ({
58
- value: a.name + ':' + r.name,
59
- label: r.name,
60
- category: a.name,
61
- section: 'Saved logins',
62
- hint: (r.isActive ? Theme.ok('in the sandbox') : '') +
63
- (r.isActive && r.isDefault ? Theme.muted(' · ') : '') +
64
- (r.isDefault ? Theme.accent('default') : ''),
65
- description: 'Enter makes the sandbox use this login.',
66
- details: [
67
- Theme.muted('Agent ') + a.name,
68
- Theme.muted('Email ') + safeText(r.email ?? '-'),
69
- Theme.muted('Saved ') + r.savedAt.slice(0, 16).replace('T', ' '),
70
- ],
71
- })),
72
- ];
73
- }),
27
+ items: m.agents.flatMap((a) => menuView(agentPage(a), { category: a.name, refresh: false }).items),
74
28
  empty: 'No agents.',
75
- actions: accountActions(m.agents),
76
- enterLabel: (_category, id) => (id === SAVE_SANDBOX || id === SAVE_PC ? 'save' : id && isLogin(id) ? 'use' : ''),
77
- };
78
- }
79
- function accountActions(agents) {
80
- return (category) => {
81
- const agent = agents.find((a) => a.name === category);
82
- if (!agent?.kept)
83
- return [];
84
- return [
85
- { key: 's', label: 'save sandbox login', importance: 3 },
86
- ...(agent.canSavePc ? [{ key: 'p', label: 'save PC login', importance: 3 }] : []),
87
- { key: 'd', label: 'make default', importance: 1, applies: isLogin },
88
- { key: 'r', label: 'rename', importance: 2, applies: isLogin },
89
- { key: 'x', label: 'remove', importance: 1, applies: isLogin },
90
- ];
29
+ actions: (category) => viewOf(m, category).actions,
30
+ enterLabel: (category, id) => viewOf(m, category).enterLabel(category, id),
91
31
  };
92
32
  }
93
33
  export class AccountsPage extends ListPage {
34
+ ctx;
94
35
  label = 'Accounts';
95
- model = { agents: [], rows: {} };
96
- service;
36
+ model = { agent: 'claude', agents: [] };
37
+ operations;
97
38
  constructor(app, ctx) {
98
39
  super(app);
99
- this.service = new AccountsService(ctx);
40
+ this.ctx = ctx;
41
+ this.operations = new MenuOperations(app, ctx);
100
42
  }
101
- load() {
102
- const agents = this.service.agents();
103
- const rows = {};
104
- for (const a of agents.filter((x) => x.kept)) {
105
- try {
106
- rows[a.name] = this.service.list(a.name);
107
- }
108
- catch {
109
- rows[a.name] = [];
110
- }
111
- }
112
- this.model = { agents, rows };
113
- return Promise.resolve();
43
+ async load() {
44
+ this.model = await readQuery(listAccounts, this.ctx);
114
45
  }
115
46
  options() {
116
47
  return accountsOptions(this.model);
117
48
  }
118
- /** The agent of the open category, and the login name of an item value ("agent:name"). */
119
- agentNow() {
120
- return this.category ?? 'claude';
121
- }
122
- static nameOf(value) {
123
- const i = value?.indexOf(':') ?? -1;
124
- return value && i >= 0 && isLogin(value) ? value.slice(i + 1) : undefined;
125
- }
126
49
  async act(result) {
127
- const agent = this.agentNow();
128
- const name = AccountsPage.nameOf(result.kind === 'pick' || result.kind === 'action' ? result.value : undefined);
129
- try {
130
- if (result.kind === 'action' && (result.key === 's' || result.key === 'p'))
131
- return await this.save(agent, result.key === 'p');
132
- if (result.kind === 'pick' && (result.value === SAVE_SANDBOX || result.value === SAVE_PC))
133
- return await this.save(agent, result.value === SAVE_PC);
134
- if (result.kind === 'pick' && name)
135
- return await this.use(agent, name);
136
- if (result.kind === 'action' && name) {
137
- if (result.key === 'd') {
138
- this.service.setDefault(name, agent);
139
- return { reload: true, notice: Theme.ok(Theme.glyph.ok + ' ' + name + ' is the default for new launches.') };
140
- }
141
- if (result.key === 'x')
142
- return await this.remove(agent, name);
143
- if (result.key === 'r')
144
- return await this.rename(agent, name);
145
- }
146
- }
147
- catch (e) {
148
- return { notice: Theme.error(Theme.glyph.cross + ' ' + errMsg(e)) };
149
- }
150
- return {};
151
- }
152
- askName(title, about, initial = '') {
153
- return this.app.text({
154
- path: ['Accounts', title],
155
- label: 'Name for this login',
156
- about: [about],
157
- initial,
158
- validate: (v) => (NAME.test(v.trim()) ? true : 'Use letters, digits, - and _ (up to 40).'),
159
- });
160
- }
161
- async save(agent, fromHost) {
162
- const name = await this.askName(fromHost ? "Save this PC's " + agent + ' login' : "Save the sandbox's " + agent + ' login', fromHost ? 'Saves the ' + agent + ' login of this PC.' : 'Saves the login you signed in with inside the sandbox.');
163
- if (!name)
164
- return {};
165
- const saved = this.service.save(name.trim(), fromHost, agent);
166
- return {
167
- reload: true,
168
- focus: agent + ':' + saved.name,
169
- notice: Theme.ok(Theme.glyph.ok + ' Saved "' + saved.name + '".'),
170
- };
171
- }
172
- async rename(agent, name) {
173
- const to = await this.askName('Rename "' + name + '"', 'The login keeps working under its new name.', name);
174
- if (!to || to.trim() === name)
175
- return {};
176
- this.service.rename(name, to.trim(), agent);
177
- return {
178
- reload: true,
179
- focus: agent + ':' + to.trim(),
180
- notice: Theme.ok(Theme.glyph.ok + ' Renamed to "' + to.trim() + '".'),
181
- };
182
- }
183
- async use(agent, name) {
184
- const account = this.service.activate(name, agent);
185
- let note = Theme.ok(Theme.glyph.ok + ' The sandbox now uses "' + account.name + '" for ' + agent + '.');
186
- if (account.note)
187
- note += ' ' + safeText(account.note);
188
- if (this.service.hasRunningSessions(agent) &&
189
- (await this.app.ask('Restart the running ' + agent + ' sessions?', ['They restart and continue their conversation where the agent can, now under the new login.'], 'Restart')))
190
- note += ' ' + safeText(await this.service.restart(agent));
191
- return { reload: true, notice: note };
192
- }
193
- async remove(agent, name) {
194
- if (!(await this.app.ask('Remove "' + name + '"?', ['The saved login is deleted from this PC.'], 'Remove', true)))
50
+ const chosen = viewOf(this.model, this.category).resolve(result);
51
+ if (!chosen)
195
52
  return {};
196
- this.service.remove(name, agent);
197
- return { reload: true, notice: Theme.ok(Theme.glyph.ok + ' Removed "' + name + '".') };
53
+ if (chosen.kind === 'refresh')
54
+ return { reload: true };
55
+ return this.operations.perform(chosen.action, [this.label], (text) => this.busy(text));
198
56
  }
199
57
  }