windows-development-sandbox 1.20.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. package/config.example.json +8 -1
  2. package/dist/app/features/access/access.def.js +5 -2
  3. package/dist/app/features/access/access.run.js +7 -3
  4. package/dist/app/features/accounts/accounts.def.d.ts +29 -1
  5. package/dist/app/features/accounts/accounts.def.js +10 -4
  6. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  7. package/dist/app/features/accounts/accounts.run.js +7 -2
  8. package/dist/app/features/accounts/services.def.d.ts +4 -1
  9. package/dist/app/features/accounts/services.def.js +15 -14
  10. package/dist/app/features/accounts/services.run.d.ts +1 -0
  11. package/dist/app/features/accounts/services.run.js +41 -15
  12. package/dist/app/features/defs.d.ts +39 -2
  13. package/dist/app/features/engine/engine.run.js +1 -1
  14. package/dist/app/features/github/github.def.d.ts +44 -3
  15. package/dist/app/features/github/github.def.js +145 -63
  16. package/dist/app/features/github/github.run.d.ts +9 -2
  17. package/dist/app/features/github/github.run.js +43 -5
  18. package/dist/app/features/health/health.def.js +8 -2
  19. package/dist/app/features/logs/logs.def.js +0 -8
  20. package/dist/app/features/projects/projects.def.js +2 -2
  21. package/dist/app/features/projects/projects.run.js +5 -5
  22. package/dist/app/features/sandbox/sandbox.def.js +7 -3
  23. package/dist/app/features/sessions/sessions.def.d.ts +4 -4
  24. package/dist/app/features/sessions/sessions.def.js +0 -5
  25. package/dist/app/features/sessions/sessions.run.d.ts +1 -1
  26. package/dist/app/features/sessions/sessions.run.js +2 -2
  27. package/dist/app/features/settings/categories.def.js +2 -0
  28. package/dist/app/features/settings/settings-rows.js +1 -1
  29. package/dist/app/features/settings/settings.def.js +1 -1
  30. package/dist/app/features/settings/settings.run.js +3 -3
  31. package/dist/app/features/storage/storage.run.js +18 -9
  32. package/dist/app/features/updates/update-lines.js +2 -2
  33. package/dist/app/features/updates/updates.def.js +1 -1
  34. package/dist/app/features/updates/updates.run.js +1 -1
  35. package/dist/app/features/web/web.def.js +2 -2
  36. package/dist/app/features/web/web.run.js +12 -4
  37. package/dist/app/kernel/errors.d.ts +7 -0
  38. package/dist/app/kernel/errors.js +18 -3
  39. package/dist/app/kernel/rpc.d.ts +5 -0
  40. package/dist/app/kernel/view.d.ts +11 -1
  41. package/dist/bin/agent-sandbox.js +2 -2
  42. package/dist/bin/{chunk-DK4NTBUF.js → chunk-JETGP2C3.js} +172 -48
  43. package/dist/bin/{chunk-2IMT7ZCT.js → chunk-XZKOPGNH.js} +1 -1
  44. package/dist/bin/{chunk-Z2P5OGKL.js → chunk-ZTTOF5V3.js} +2430 -1688
  45. package/dist/bin/claude-host.js +2 -2
  46. package/dist/bin/claude-sbx.js +2 -2
  47. package/dist/bin/codex-sbx.js +2 -2
  48. package/dist/bin/gemini-sbx.js +2 -2
  49. package/dist/bin/sandbox.js +2 -2
  50. package/dist/bin/sbx-hide.js +2 -2
  51. package/dist/bin/sbx-show.js +2 -2
  52. package/dist/cli/manifest.d.ts +2 -2
  53. package/dist/cli/manifest.js +2 -1
  54. package/dist/cli/menu/coverage-exempt.d.ts +17 -0
  55. package/dist/cli/menu/coverage-exempt.js +61 -0
  56. package/dist/cli/menu/io-menu.d.ts +2 -0
  57. package/dist/cli/menu/io-menu.js +50 -5
  58. package/dist/cli/menu/pages/accounts-page.js +1 -1
  59. package/dist/cli/menu/pages/agents-page.js +8 -2
  60. package/dist/cli/menu/pages/maintenance-page.d.ts +6 -0
  61. package/dist/cli/menu/pages/maintenance-page.js +9 -2
  62. package/dist/cli/menu/pages/sessions-page.d.ts +2 -0
  63. package/dist/cli/menu/pages/sessions-page.js +12 -4
  64. package/dist/cli/menu/pages/settings-page.js +12 -1
  65. package/dist/cli/menu/remote-menu.js +1 -1
  66. package/dist/cli/menu/shell.d.ts +5 -0
  67. package/dist/cli/menu/shell.js +13 -0
  68. package/dist/cli/report.js +2 -0
  69. package/dist/cli/tui/app.d.ts +5 -0
  70. package/dist/cli/tui/app.js +2 -0
  71. package/dist/core/config/defaults.js +3 -1
  72. package/dist/core/schema/accounts.d.ts +6 -0
  73. package/dist/core/schema/accounts.js +13 -11
  74. package/dist/core/schema/config.d.ts +20 -8
  75. package/dist/core/schema/config.js +4 -4
  76. package/dist/core/schema/github.js +1 -1
  77. package/dist/core/schema/profile.js +8 -4
  78. package/dist/core/schema/resume.js +1 -1
  79. package/dist/core/schema/sandbox.js +3 -3
  80. package/dist/core/schema/vpn.js +1 -1
  81. package/dist/core/schema/web.js +3 -3
  82. package/dist/core/types.d.ts +6 -0
  83. package/dist/core/util/errors.d.ts +11 -1
  84. package/dist/core/util/errors.js +7 -1
  85. package/dist/core/util/index.d.ts +1 -1
  86. package/dist/core/util/index.js +1 -1
  87. package/dist/guest/accounts/adapter.d.ts +2 -0
  88. package/dist/guest/accounts/adapters.js +4 -0
  89. package/dist/guest/accounts/apply.d.ts +6 -2
  90. package/dist/guest/accounts/kinds/cfx.d.ts +7 -0
  91. package/dist/guest/accounts/kinds/cfx.js +33 -3
  92. package/dist/guest/accounts/kinds/comet.d.ts +7 -0
  93. package/dist/guest/accounts/kinds/comet.js +50 -0
  94. package/dist/guest/accounts/kinds/perplexity.d.ts +2 -0
  95. package/dist/guest/accounts/kinds/perplexity.js +12 -0
  96. package/dist/guest/accounts/watch.d.ts +2 -0
  97. package/dist/guest/accounts/watch.js +12 -2
  98. package/dist/guest/agents/agent-installer.js +1 -1
  99. package/dist/guest/agents/profile-links.d.ts +2 -0
  100. package/dist/guest/agents/profile-links.js +18 -4
  101. package/dist/guest/apps/after-install.js +19 -0
  102. package/dist/guest/apps/app-installer.d.ts +11 -0
  103. package/dist/guest/apps/app-installer.js +69 -6
  104. package/dist/guest/apps/comet-unpack.d.ts +20 -0
  105. package/dist/guest/apps/comet-unpack.js +127 -0
  106. package/dist/guest/apps/index.d.ts +1 -1
  107. package/dist/guest/apps/index.js +1 -1
  108. package/dist/guest/apps/resolvers-agents-web.d.ts +2 -0
  109. package/dist/guest/apps/resolvers-agents-web.js +7 -0
  110. package/dist/guest/apps/resolvers.js +2 -0
  111. package/dist/guest/apps/shortcuts.d.ts +2 -0
  112. package/dist/guest/apps/shortcuts.js +1 -0
  113. package/dist/guest/apps/unpack.js +14 -4
  114. package/dist/guest/boot/boot.d.ts +45 -16
  115. package/dist/guest/boot/boot.js +316 -145
  116. package/dist/guest/boot/graph.d.ts +252 -0
  117. package/dist/guest/boot/graph.js +257 -0
  118. package/dist/guest/boot/guide-lines.d.ts +25 -0
  119. package/dist/guest/boot/guide-lines.js +41 -0
  120. package/dist/guest/boot/guide.d.ts +1 -4
  121. package/dist/guest/boot/guide.js +6 -8
  122. package/dist/guest/boot/runner.d.ts +77 -0
  123. package/dist/guest/boot/runner.js +215 -0
  124. package/dist/guest/browser/cdp.d.ts +71 -0
  125. package/dist/guest/browser/cdp.js +306 -0
  126. package/dist/guest/browser/comet.d.ts +28 -0
  127. package/dist/guest/browser/comet.js +155 -0
  128. package/dist/guest/daemon/project-provisioner.js +6 -1
  129. package/dist/guest/devtools/fivem.d.ts +1 -1
  130. package/dist/guest/devtools/fivem.js +243 -3
  131. package/dist/guest/entries/daemon.js +2 -0
  132. package/dist/guest/runtime/log.d.ts +12 -0
  133. package/dist/guest/runtime/log.js +29 -5
  134. package/dist/guest/runtime/pools.d.ts +24 -0
  135. package/dist/guest/runtime/pools.js +60 -0
  136. package/dist/guest/runtime/process.d.ts +4 -0
  137. package/dist/guest/runtime/process.js +38 -1
  138. package/dist/guest/runtime/status.d.ts +5 -1
  139. package/dist/guest/runtime/status.js +19 -0
  140. package/dist/guest/setup/addon-mcp.d.ts +1 -1
  141. package/dist/guest/setup/addon-mcp.js +52 -12
  142. package/dist/guest/setup/agent-addons.d.ts +3 -2
  143. package/dist/guest/setup/agent-addons.js +12 -3
  144. package/dist/guest/setup/environment.d.ts +1 -1
  145. package/dist/guest/setup/environment.js +25 -12
  146. package/dist/guest/setup/headroom.d.ts +8 -3
  147. package/dist/guest/setup/headroom.js +44 -15
  148. package/dist/guest/setup/path-plan.d.ts +28 -0
  149. package/dist/guest/setup/path-plan.js +69 -2
  150. package/dist/guest/setup/shell-path.d.ts +1 -1
  151. package/dist/guest/setup/shell-path.js +3 -3
  152. package/dist/guest/toolchains/fivem/artifacts.d.ts +48 -1
  153. package/dist/guest/toolchains/fivem/artifacts.js +97 -4
  154. package/dist/guest/toolchains/fivem/fivem.d.ts +32 -1
  155. package/dist/guest/toolchains/fivem/fivem.js +168 -3
  156. package/dist/guest/toolchains/fivem/scaffold.d.ts +35 -0
  157. package/dist/guest/toolchains/fivem/scaffold.js +105 -0
  158. package/dist/guest/toolchains/fivem/serve-plan.d.ts +34 -0
  159. package/dist/guest/toolchains/fivem/serve-plan.js +61 -0
  160. package/dist/guest/toolchains/languages/go.js +1 -1
  161. package/dist/guest/toolchains/languages/node.js +2 -1
  162. package/dist/guest/toolchains/languages/php.d.ts +2 -0
  163. package/dist/guest/toolchains/languages/php.js +13 -1
  164. package/dist/guest/toolchains/languages/python-tools.js +1 -1
  165. package/dist/guest/toolchains/languages/ruby.js +1 -1
  166. package/dist/guest/toolchains/native/binstall.js +1 -1
  167. package/dist/guest/toolchains/native/msvc/packages.js +10 -4
  168. package/dist/guest/toolchains/native/rust.d.ts +2 -0
  169. package/dist/guest/toolchains/native/rust.js +11 -4
  170. package/dist/guest/toolchains/native/unreal.d.ts +2 -0
  171. package/dist/guest/toolchains/native/unreal.js +16 -6
  172. package/dist/guest/toolchains/native/vcruntime.d.ts +2 -0
  173. package/dist/guest/toolchains/native/vcruntime.js +10 -2
  174. package/dist/guest/toolchains/native/visual-studio.d.ts +3 -0
  175. package/dist/guest/toolchains/native/visual-studio.js +44 -26
  176. package/dist/guest/toolchains/native/vs-request.d.ts +2 -0
  177. package/dist/guest/toolchains/native/vs-request.js +2 -0
  178. package/dist/guest/toolchains/plan.js +19 -8
  179. package/dist/guest/toolchains/scheduler.d.ts +2 -21
  180. package/dist/guest/toolchains/scheduler.js +7 -121
  181. package/dist/guest/toolchains/setup.d.ts +15 -2
  182. package/dist/guest/toolchains/setup.js +39 -20
  183. package/dist/guest/toolchains/split.d.ts +28 -0
  184. package/dist/guest/toolchains/split.js +60 -0
  185. package/dist/guest/toolchains/steam/client.js +2 -1
  186. package/dist/guest/toolchains/step-scheduler.d.ts +51 -0
  187. package/dist/guest/toolchains/step-scheduler.js +147 -0
  188. package/dist/guest/toolchains/step.d.ts +13 -0
  189. package/dist/guest/toolchains/tools/git.js +18 -0
  190. package/dist/guest/vpn/openvpn.js +3 -4
  191. package/dist/guest/vpn/wireguard.js +11 -4
  192. package/dist/host/accounts/deliver.js +7 -0
  193. package/dist/host/accounts/handoff.js +2 -6
  194. package/dist/host/accounts/index.d.ts +1 -1
  195. package/dist/host/accounts/index.js +1 -1
  196. package/dist/host/accounts/kinds/cfx.d.ts +1 -1
  197. package/dist/host/accounts/kinds/cfx.js +47 -4
  198. package/dist/host/accounts/kinds/comet.d.ts +2 -0
  199. package/dist/host/accounts/kinds/comet.js +6 -0
  200. package/dist/host/accounts/kinds/perplexity.d.ts +2 -0
  201. package/dist/host/accounts/kinds/perplexity.js +30 -0
  202. package/dist/host/accounts/leases.d.ts +7 -1
  203. package/dist/host/accounts/leases.js +13 -2
  204. package/dist/host/accounts/source.d.ts +7 -1
  205. package/dist/host/accounts/source.js +27 -0
  206. package/dist/host/accounts/sources.js +4 -0
  207. package/dist/host/github/deliver.d.ts +1 -1
  208. package/dist/host/github/deliver.js +20 -1
  209. package/dist/host/github/index.d.ts +2 -1
  210. package/dist/host/github/index.js +1 -0
  211. package/dist/host/github/token.d.ts +13 -1
  212. package/dist/host/github/token.js +19 -2
  213. package/dist/host/github/verify.d.ts +27 -0
  214. package/dist/host/github/verify.js +61 -0
  215. package/dist/host/launch/hints/fivem.d.ts +3 -1
  216. package/dist/host/launch/hints/fivem.js +68 -2
  217. package/dist/host/launch/session-file.js +4 -0
  218. package/dist/host/launch/toolchains.d.ts +2 -1
  219. package/dist/host/launch/toolchains.js +5 -3
  220. package/dist/host/vpn/nordvpn.d.ts +2 -4
  221. package/dist/host/vpn/nordvpn.js +2 -24
  222. package/dist/runtime/agent.js +405 -90
  223. package/dist/runtime/daemon.js +3010 -1383
  224. package/dist/runtime/db.js +333 -90
  225. package/dist/runtime/main.js +4720 -1954
  226. package/dist/runtime/netproxy.js +286 -69
  227. package/dist/runtime/tool.js +2852 -1780
  228. package/dist/runtime/view.js +286 -69
  229. package/dist/selftest/agent-paths.test.js +39 -1
  230. package/dist/selftest/agents-web.test.d.ts +2 -0
  231. package/dist/selftest/agents-web.test.js +647 -0
  232. package/dist/selftest/app.test.js +5 -2
  233. package/dist/selftest/boot-runner.test.d.ts +2 -0
  234. package/dist/selftest/boot-runner.test.js +456 -0
  235. package/dist/selftest/channel.test.js +15 -0
  236. package/dist/selftest/fivem.test.js +249 -3
  237. package/dist/selftest/github.test.js +94 -9
  238. package/dist/selftest/guest-boot.test.js +3 -0
  239. package/dist/selftest/health.test.js +1 -1
  240. package/dist/selftest/index.js +8 -0
  241. package/dist/selftest/layout.test.js +5 -0
  242. package/dist/selftest/menu-coverage.test.d.ts +2 -0
  243. package/dist/selftest/menu-coverage.test.js +46 -0
  244. package/dist/selftest/menu-screens.js +37 -1
  245. package/dist/selftest/persisted-installs.test.js +6 -3
  246. package/dist/selftest/service-accounts.test.js +3 -2
  247. package/dist/selftest/support/engine-golden.js +27 -0
  248. package/dist/selftest/support/fixtures.d.ts +6 -0
  249. package/dist/selftest/support/web-preview.d.ts +34 -1
  250. package/dist/selftest/support/web-preview.js +21 -18
  251. package/dist/selftest/toolchains.test.js +23 -1
  252. package/dist/selftest/ui-text.test.d.ts +7 -0
  253. package/dist/selftest/ui-text.test.js +300 -0
  254. package/dist/shared/accounts/index.d.ts +2 -0
  255. package/dist/shared/accounts/index.js +2 -0
  256. package/dist/shared/accounts/kinds/comet.d.ts +12 -0
  257. package/dist/shared/accounts/kinds/comet.js +64 -0
  258. package/dist/shared/accounts/kinds/perplexity.d.ts +8 -0
  259. package/dist/shared/accounts/kinds/perplexity.js +37 -0
  260. package/dist/shared/accounts/kinds.d.ts +24 -5
  261. package/dist/shared/accounts/kinds.js +86 -4
  262. package/dist/shared/accounts/payloads.d.ts +81 -0
  263. package/dist/shared/accounts/payloads.js +39 -1
  264. package/dist/shared/apps/agent-addons.d.ts +33 -5
  265. package/dist/shared/apps/agent-addons.js +95 -3
  266. package/dist/shared/apps/catalogue-agents-web.d.ts +14 -0
  267. package/dist/shared/apps/catalogue-agents-web.js +112 -0
  268. package/dist/shared/apps/catalogue-modding.js +32 -1
  269. package/dist/shared/apps/catalogue.d.ts +27 -3
  270. package/dist/shared/apps/catalogue.js +2 -1
  271. package/dist/shared/apps/index.d.ts +3 -1
  272. package/dist/shared/apps/index.js +3 -1
  273. package/dist/shared/channel/schema.d.ts +21 -3
  274. package/dist/shared/channel/schema.js +7 -0
  275. package/dist/shared/channel/secrets.d.ts +19 -0
  276. package/dist/shared/concurrency/index.d.ts +3 -0
  277. package/dist/shared/concurrency/index.js +3 -0
  278. package/dist/shared/concurrency/installer-retry.d.ts +6 -0
  279. package/dist/shared/concurrency/installer-retry.js +10 -0
  280. package/dist/shared/concurrency/limiter.d.ts +19 -0
  281. package/dist/shared/concurrency/limiter.js +67 -0
  282. package/dist/shared/concurrency/pools.d.ts +7 -0
  283. package/dist/shared/concurrency/pools.js +9 -0
  284. package/dist/shared/download/archive.d.ts +2 -0
  285. package/dist/shared/download/archive.js +11 -1
  286. package/dist/shared/download/bounded-fetch.d.ts +13 -0
  287. package/dist/shared/download/bounded-fetch.js +40 -0
  288. package/dist/shared/download/downloader.d.ts +5 -0
  289. package/dist/shared/download/downloader.js +50 -38
  290. package/dist/shared/download/index.d.ts +2 -1
  291. package/dist/shared/download/index.js +2 -1
  292. package/dist/shared/readiness.d.ts +2 -2
  293. package/dist/shared/readiness.js +2 -2
  294. package/dist/web/index.html +1 -1
  295. package/dist/web/{main-OUUQYNK4.js → main-CCILLX2M.js} +67 -67
  296. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  297. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  298. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  299. package/package.json +1 -1
  300. package/sandbox/addons/browser-use-mcp/requirements.in +1 -0
  301. package/sandbox/addons/browser-use-mcp/requirements.txt +2350 -0
  302. package/sandbox/addons/chrome-devtools-mcp/package-lock.json +38 -0
  303. package/sandbox/addons/chrome-devtools-mcp/package.json +7 -0
  304. package/sandbox/addons/comet-mcp/package-lock.json +1277 -0
  305. package/sandbox/addons/comet-mcp/package.json +7 -0
  306. package/sandbox/addons/perplexity-mcp/package-lock.json +1655 -0
  307. package/sandbox/addons/perplexity-mcp/package.json +7 -0
  308. package/sandbox/scripts/add-firewall-port.ps1 +18 -4
  309. package/sandbox/scripts/set-machine-environment.ps1 +30 -15
  310. package/sandbox/templates/fivem/README.txt +6 -2
  311. package/sandbox/templates/fivem/cs/Client/Client.csproj +15 -0
  312. package/sandbox/templates/fivem/cs/Client/ClientMain.cs +20 -0
  313. package/sandbox/templates/fivem/cs/Server/Server.csproj +14 -0
  314. package/sandbox/templates/fivem/cs/Server/ServerMain.cs +20 -0
  315. package/sandbox/templates/fivem/cs/fxmanifest.lua +11 -0
  316. package/sandbox/templates/fivem/js/client.js +12 -0
  317. package/sandbox/templates/fivem/js/fxmanifest.lua +9 -0
  318. package/sandbox/templates/fivem/js/server.js +6 -0
  319. package/sandbox/templates/fivem/lua/client.lua +8 -0
  320. package/sandbox/templates/fivem/lua/fxmanifest.lua +10 -0
  321. package/sandbox/templates/fivem/lua/server.lua +6 -0
  322. package/sandbox/templates/fivem/server.cfg +37 -0
  323. package/sandbox/templates/fivem/ts/build.js +17 -0
  324. package/sandbox/templates/fivem/ts/fxmanifest.lua +9 -0
  325. package/sandbox/templates/fivem/ts/package.json +16 -0
  326. package/sandbox/templates/fivem/ts/src/client/client.ts +12 -0
  327. package/sandbox/templates/fivem/ts/src/client/tsconfig.json +13 -0
  328. package/sandbox/templates/fivem/ts/src/server/server.ts +6 -0
  329. package/sandbox/templates/fivem/ts/src/server/tsconfig.json +13 -0
  330. package/schemas/config.schema.json +56 -27
  331. package/schemas/sandbox-config.schema.json +37 -14
@@ -100,6 +100,12 @@
100
100
  },
101
101
  "appstore": {
102
102
  "share": false
103
+ },
104
+ "perplexity": {
105
+ "share": false
106
+ },
107
+ "comet": {
108
+ "share": false
103
109
  }
104
110
  },
105
111
  "pcInstalls": {
@@ -421,7 +427,8 @@
421
427
  "CODEX_HOME": "codex"
422
428
  },
423
429
  "loginFiles": [
424
- "auth.json"
430
+ "auth.json",
431
+ ".credentials.json"
425
432
  ],
426
433
  "hostDir": "~/.codex"
427
434
  },
@@ -3,7 +3,7 @@
3
3
  // page; access.run.ts does the work. Everything here is the owner's: a device or another Windows user never manages
4
4
  // access, whatever their role.
5
5
  import { z } from 'zod';
6
- import { action, defineOperation, defineQuery, defineView, fieldOf } from '../../kernel/index.js';
6
+ import { action, defineOperation, defineQuery, defineView, fieldOf, link, } from '../../kernel/index.js';
7
7
  const RoleSchema = z.enum(['view', 'control']);
8
8
  export const DeviceRowSchema = z.object({
9
9
  id: z.string().describe('Its id (for revoke)'),
@@ -253,11 +253,14 @@ export function accessPage(o, now = Date.now()) {
253
253
  label: 'Windows sign-in',
254
254
  value: o.windowsSignIn ? 'on' : 'off',
255
255
  tone: o.windowsSignIn ? 'ok' : 'muted',
256
- description: 'They run sandbox remote (or sandbox remote --browser) as themselves. Turn on web.remote.windowsSignIn and list them in web.remote.users (Settings).',
256
+ description: 'They sign in to the web UI with their own Windows account. Turn it on and list them in Settings (web.remote.windowsSignIn and web.remote.users).',
257
257
  },
258
258
  ...o.users.map((u, i) => ({ id: 'user-' + i, label: u.name, value: u.role })),
259
259
  ],
260
260
  items: windowsItems,
261
+ actions: [
262
+ link({ kind: 'setting', key: 'web.remote.windowsSignIn' }, 'Windows sign-in setting…', { verb: 'settings' }),
263
+ ],
261
264
  },
262
265
  ],
263
266
  actions: [action(revokeAllAccess, {}, { key: 'X', verb: 'sign out all' })],
@@ -3,7 +3,7 @@
3
3
  // remote settings, the firewall rule and the network check of LAN mode. The one-time code is returned once and only
4
4
  // its hash is kept.
5
5
  import { requireOnPc } from '../../../cli/commands/context.js';
6
- import { fail } from '../../../core/util/index.js';
6
+ import { fail, failWith } from '../../../core/util/index.js';
7
7
  import { AccessStore, addRuleRequest, applyFirewall, chooseLanAddress, lanUrl, networkProblem, networkProfile, removeRuleRequest, showCode, } from '../../../host/remote/index.js';
8
8
  import { SecretStore } from '../../../host/secrets/index.js';
9
9
  import { protectPrivateFolder } from '../../../host/sharing/index.js';
@@ -68,7 +68,11 @@ export const accessStatusRun = implement(accessStatus, (ctx) => {
68
68
  export const allowDeviceRun = implement(allowDevice, (ctx, input) => {
69
69
  requireOnPc('web');
70
70
  if (!ctx.loaded.config.web.remote.lan.enabled)
71
- fail('LAN mode is off, so no device on your network can reach the web UI.', 'Turn it on first: sandbox web lan-on');
71
+ failWith('LAN mode is off, so no device on your network can reach the web UI.', 'Turn it on first.', {
72
+ op: 'access.lanOn',
73
+ label: 'Turn on LAN mode',
74
+ cli: 'sandbox web lan-on',
75
+ });
72
76
  const { code, expiresAt } = accessStoreOf(ctx).newDeviceCode(input.role);
73
77
  const lan = lanStateOf(ctx);
74
78
  return { code: showCode(code), expiresAt, role: input.role, address: lan.url, fingerprint: lan.fingerprint };
@@ -76,7 +80,7 @@ export const allowDeviceRun = implement(allowDevice, (ctx, input) => {
76
80
  export const revokeAccessRun = implement(revokeAccess, (ctx, input) => {
77
81
  requireOnPc('web');
78
82
  if (!accessStoreOf(ctx).revoke(input.id))
79
- fail('There is no device or sign-in ' + input.id + '.', 'See sandbox web devices.');
83
+ fail('There is no device or sign-in ' + input.id + '.', 'Check the list of devices and sign-ins.');
80
84
  return { message: 'Signed out. Its open pages close within half a minute.' };
81
85
  });
82
86
  export const revokeAllAccessRun = implement(revokeAllAccess, async (ctx, _input, io) => {
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { type Page, type Section } from '../../kernel/index.js';
3
+ import { type GithubStatus } from '../github/github.def.js';
3
4
  import { type ServicesList } from './services.def.js';
4
5
  export declare const AccountRowSchema: z.ZodObject<{
5
6
  name: z.ZodString;
@@ -70,6 +71,7 @@ export declare const AccountsListSchema: z.ZodObject<{
70
71
  summary: z.ZodNullable<z.ZodString>;
71
72
  heldBy: z.ZodNullable<z.ZodString>;
72
73
  usedBy: z.ZodArray<z.ZodString>;
74
+ usedFor: z.ZodString;
73
75
  warnings: z.ZodArray<z.ZodString>;
74
76
  canImport: z.ZodBoolean;
75
77
  canLogin: z.ZodBoolean;
@@ -118,6 +120,7 @@ export declare const listAccounts: import("../../kernel/define.js").QueryDef<z.Z
118
120
  summary: z.ZodNullable<z.ZodString>;
119
121
  heldBy: z.ZodNullable<z.ZodString>;
120
122
  usedBy: z.ZodArray<z.ZodString>;
123
+ usedFor: z.ZodString;
121
124
  warnings: z.ZodArray<z.ZodString>;
122
125
  canImport: z.ZodBoolean;
123
126
  canLogin: z.ZodBoolean;
@@ -164,7 +167,7 @@ export declare const removeAccount: import("../../kernel/define.js").OperationDe
164
167
  /** One agent's card: its save rows and logins (a card to pick from), or the note that its login is not kept. */
165
168
  export declare function agentSection(a: AgentAccounts): Section;
166
169
  /** The web's page: one card per agent (its logins and the save rows), then one section per service sign-in. */
167
- export declare function accountsPage(o: AccountsList, services?: ServicesList): Page;
170
+ export declare function accountsPage(o: AccountsList, services?: ServicesList, github?: GithubStatus): Page;
168
171
  /**
169
172
  * One agent's page for the menu: its section, and the keys of its save rows (s, p) which the menu's key bar shows
170
173
  * while the agent's category is open. The keys of a login row (d, r, x) are on the row itself.
@@ -207,6 +210,7 @@ export declare const accountsView: import("../../kernel/define.js").ViewDef<{
207
210
  summary: z.ZodNullable<z.ZodString>;
208
211
  heldBy: z.ZodNullable<z.ZodString>;
209
212
  usedBy: z.ZodArray<z.ZodString>;
213
+ usedFor: z.ZodString;
210
214
  warnings: z.ZodArray<z.ZodString>;
211
215
  canImport: z.ZodBoolean;
212
216
  canLogin: z.ZodBoolean;
@@ -231,6 +235,7 @@ export declare const accountsView: import("../../kernel/define.js").ViewDef<{
231
235
  summary: z.ZodNullable<z.ZodString>;
232
236
  heldBy: z.ZodNullable<z.ZodString>;
233
237
  usedBy: z.ZodArray<z.ZodString>;
238
+ usedFor: z.ZodString;
234
239
  warnings: z.ZodArray<z.ZodString>;
235
240
  canImport: z.ZodBoolean;
236
241
  canLogin: z.ZodBoolean;
@@ -238,4 +243,27 @@ export declare const accountsView: import("../../kernel/define.js").ViewDef<{
238
243
  ready: z.ZodBoolean;
239
244
  }, z.core.$strip>>;
240
245
  }, z.core.$strip>, "accounts.services">;
246
+ github: import("../../kernel/define.js").QueryDef<z.ZodObject<{}, z.core.$strict>, z.ZodObject<{
247
+ shareToken: z.ZodBoolean;
248
+ gitAccess: z.ZodEnum<{
249
+ readonly: "readonly";
250
+ none: "none";
251
+ full: "full";
252
+ }>;
253
+ token: z.ZodEnum<{
254
+ none: "none";
255
+ saved: "saved";
256
+ unreadable: "unreadable";
257
+ }>;
258
+ kind: z.ZodNullable<z.ZodEnum<{
259
+ "fine-grained": "fine-grained";
260
+ classic: "classic";
261
+ }>>;
262
+ savedAt: z.ZodNullable<z.ZodString>;
263
+ login: z.ZodNullable<z.ZodString>;
264
+ expiresAt: z.ZodNullable<z.ZodString>;
265
+ repoCount: z.ZodNullable<z.ZodNumber>;
266
+ checkedAt: z.ZodNullable<z.ZodString>;
267
+ tokenUrl: z.ZodString;
268
+ }, z.core.$strip>, "github.status">;
241
269
  }, Record<string, never>, "accounts">;
@@ -3,6 +3,7 @@
3
3
  // accounts.run.ts does the work over AccountsService.
4
4
  import { z } from 'zod';
5
5
  import { action, defineOperation, defineQuery, defineView, plural, } from '../../kernel/index.js';
6
+ import { githubLogin, githubLogout, githubStatus, githubSection } from '../github/github.def.js';
6
7
  import { setSetting } from '../settings/settings.def.js';
7
8
  import { listServices, SERVICE_OPERATIONS, serviceSections, ServiceRowSchema, } from './services.def.js';
8
9
  const AgentSchema = z.string().default('claude').describe('whose login: an agent that keeps one (default: claude)');
@@ -279,8 +280,11 @@ export function agentSection(a) {
279
280
  };
280
281
  }
281
282
  /** The web's page: one card per agent (its logins and the save rows), then one section per service sign-in. */
282
- export function accountsPage(o, services = { services: o.services }) {
283
- return { title: 'Accounts', sections: [...o.agents.map(agentSection), ...serviceSections(services)] };
283
+ export function accountsPage(o, services = { services: o.services }, github) {
284
+ return {
285
+ title: 'Accounts',
286
+ sections: [...o.agents.map(agentSection), ...serviceSections(services), ...(github ? [githubSection(github)] : [])],
287
+ };
284
288
  }
285
289
  /**
286
290
  * One agent's page for the menu: its section, and the keys of its save rows (s, p) which the menu's key bar shows
@@ -306,7 +310,7 @@ export const accountsView = defineView({
306
310
  id: 'accounts',
307
311
  title: 'Accounts',
308
312
  summary: 'Logins saved on this PC for each agent (every launch starts with the default; "Use this login" switches now), and the service sign-ins sandboxes may get (Epic, Steam, Unity, signing keys ...).',
309
- queries: { accounts: listAccounts, services: listServices },
313
+ queries: { accounts: listAccounts, services: listServices, github: githubStatus },
310
314
  operations: [
311
315
  saveAccount,
312
316
  useAccount,
@@ -314,7 +318,9 @@ export const accountsView = defineView({
314
318
  renameAccount,
315
319
  removeAccount,
316
320
  ...SERVICE_OPERATIONS,
321
+ githubLogin,
322
+ githubLogout,
317
323
  setSetting,
318
324
  ],
319
- build: ({ accounts, services }) => accountsPage(accounts, services),
325
+ build: ({ accounts, services, github }) => accountsPage(accounts, services, github),
320
326
  });
@@ -35,6 +35,7 @@ export declare const listAccountsRun: import("../../kernel/define.js").Implement
35
35
  summary: import("zod").ZodNullable<import("zod").ZodString>;
36
36
  heldBy: import("zod").ZodNullable<import("zod").ZodString>;
37
37
  usedBy: import("zod").ZodArray<import("zod").ZodString>;
38
+ usedFor: import("zod").ZodString;
38
39
  warnings: import("zod").ZodArray<import("zod").ZodString>;
39
40
  canImport: import("zod").ZodBoolean;
40
41
  canLogin: import("zod").ZodBoolean;
@@ -1,7 +1,7 @@
1
1
  // The accounts feature's work: the saved logins of each agent, and saving, using, defaulting, renaming and removing
2
2
  // them (through AccountsService). Talks only through io; prints nothing. Emails and the sandbox's own words go through
3
3
  // safeText. Logins are never read here: the store keeps them sealed, and outputs hold names, emails and dates only.
4
- import { fail, safeText } from '../../../core/util/index.js';
4
+ import { fail, failWith, safeText } from '../../../core/util/index.js';
5
5
  import { AccountsService } from '../../../cli/services/index.js';
6
6
  import { AccountLeases, ServiceAccountStore } from '../../../host/accounts/index.js';
7
7
  import { SERVICE_KINDS } from '../../../shared/accounts/index.js';
@@ -48,7 +48,12 @@ async function accountName(io, service, verb, agent, given) {
48
48
  }
49
49
  const rows = service.list(agent);
50
50
  if (!rows.length)
51
- fail('No saved accounts.', 'Sign in inside the sandbox, then run: sandbox account save <name>');
51
+ failWith('No saved accounts.', 'Sign in inside the sandbox, then save the login.', {
52
+ op: 'accounts.save',
53
+ input: { agent },
54
+ label: 'Save a login…',
55
+ cli: 'sandbox account save <name>',
56
+ });
52
57
  const picked = await io.choose({
53
58
  title: 'Which account?',
54
59
  choices: rows.map((a) => {
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { type Page, type Section } from '../../kernel/index.js';
3
3
  /** The kinds, as the help says them (the self-test checks this against shared/accounts SERVICE_KINDS). */
4
- export declare const SERVICE_NAMES_TEXT = "epic, steam, unity, cfx, keystore, play, expo or appstore";
4
+ export declare const SERVICE_NAMES_TEXT = "epic, steam, unity, cfx, keystore, play, expo, appstore, perplexity or comet";
5
5
  export declare const ServiceRowSchema: z.ZodObject<{
6
6
  kind: z.ZodString;
7
7
  label: z.ZodString;
@@ -16,6 +16,7 @@ export declare const ServiceRowSchema: z.ZodObject<{
16
16
  summary: z.ZodNullable<z.ZodString>;
17
17
  heldBy: z.ZodNullable<z.ZodString>;
18
18
  usedBy: z.ZodArray<z.ZodString>;
19
+ usedFor: z.ZodString;
19
20
  warnings: z.ZodArray<z.ZodString>;
20
21
  canImport: z.ZodBoolean;
21
22
  canLogin: z.ZodBoolean;
@@ -38,6 +39,7 @@ export declare const ServicesListSchema: z.ZodObject<{
38
39
  summary: z.ZodNullable<z.ZodString>;
39
40
  heldBy: z.ZodNullable<z.ZodString>;
40
41
  usedBy: z.ZodArray<z.ZodString>;
42
+ usedFor: z.ZodString;
41
43
  warnings: z.ZodArray<z.ZodString>;
42
44
  canImport: z.ZodBoolean;
43
45
  canLogin: z.ZodBoolean;
@@ -65,6 +67,7 @@ export declare const listServices: import("../../kernel/define.js").QueryDef<z.Z
65
67
  summary: z.ZodNullable<z.ZodString>;
66
68
  heldBy: z.ZodNullable<z.ZodString>;
67
69
  usedBy: z.ZodArray<z.ZodString>;
70
+ usedFor: z.ZodString;
68
71
  warnings: z.ZodArray<z.ZodString>;
69
72
  canImport: z.ZodBoolean;
70
73
  canLogin: z.ZodBoolean;
@@ -1,13 +1,14 @@
1
- // Service sign-ins for sandboxes (accounts.<kind>.share): Epic, Steam, Unity, Cfx.re, signing keys and app-store
2
- // keys. Whether each one is shared and saved (where it came from and when, never its value), taking one from this PC
3
- // or a file, typing one, and forgetting it. Pure: schemas, labels and page builders; services.run.ts does the work.
4
- // The kinds live in shared/accounts (a def imports no shared code): the query's rows carry everything a page shows.
1
+ // Service sign-ins for sandboxes (accounts.<kind>.share): Epic, Steam, Unity, Cfx.re, signing keys, app-store keys
2
+ // and Perplexity (its API key, Comet's sign-in). Whether each one is shared and saved (where it came from and when,
3
+ // never its value), taking one from this PC or a file, typing one, and forgetting it. Pure: schemas, labels and page
4
+ // builders; services.run.ts does the work. The kinds live in shared/accounts (a def imports no shared code): the
5
+ // query's rows carry everything a page shows.
5
6
  import { z } from 'zod';
6
7
  import { action } from '../../kernel/index.js';
7
8
  import { defineOperation, defineQuery } from '../../kernel/index.js';
8
9
  import { setSetting } from '../settings/settings.def.js';
9
10
  /** The kinds, as the help says them (the self-test checks this against shared/accounts SERVICE_KINDS). */
10
- export const SERVICE_NAMES_TEXT = 'epic, steam, unity, cfx, keystore, play, expo or appstore';
11
+ export const SERVICE_NAMES_TEXT = 'epic, steam, unity, cfx, keystore, play, expo, appstore, perplexity or comet';
11
12
  const KindSchema = z
12
13
  .string()
13
14
  .max(40)
@@ -22,7 +23,8 @@ export const ServiceRowSchema = z.object({
22
23
  savedAt: z.string().nullable().describe('When it was saved'),
23
24
  summary: z.string().nullable().describe('Which account (never the secret)'),
24
25
  heldBy: z.string().nullable().describe('The data set whose sandbox holds it now (one-holder services)'),
25
- usedBy: z.array(z.string()).describe('The toolchains it is handed over for'),
26
+ usedBy: z.array(z.string()).describe('The toolchains (or apps) it is handed over for'),
27
+ usedFor: z.string().describe('The same, in words ("unreal", "the Comet app")'),
26
28
  warnings: z.array(z.string()).describe('What everyone who shares it must know'),
27
29
  canImport: z.boolean().describe('It can be taken from this PC or a file (sandbox account import)'),
28
30
  canLogin: z.boolean().describe('It can be typed (sandbox account login)'),
@@ -127,13 +129,12 @@ function serviceActions(s) {
127
129
  : []),
128
130
  ];
129
131
  }
130
- /** How to get a first sign-in, in words. */
132
+ /** How to get a first sign-in, in words (the actions below do it). */
131
133
  function howTo(s) {
132
- const ways = [
133
- ...(s.canImport ? ['sandbox account import ' + s.kind + (s.needsFile ? ' --from <file>' : '')] : []),
134
- ...(s.canLogin ? ['sandbox account login ' + s.kind] : []),
135
- ];
136
- return ways.length ? ways.join(', or ') : 'sign in once inside a sandbox';
134
+ const ways = [...(s.canImport ? ['import it'] : []), ...(s.canLogin ? ['type it in'] : [])];
135
+ return ways.length
136
+ ? ways.join(' or ')
137
+ : "sign in once inside a sandbox (it can't be copied from this PC: Windows locks it to your PC account)";
137
138
  }
138
139
  /** One service's section: its facts, its warnings and its actions. */
139
140
  export function serviceSection(s) {
@@ -141,9 +142,9 @@ export function serviceSection(s) {
141
142
  {
142
143
  id: s.kind + ':share',
143
144
  label: 'Shared with sandboxes',
144
- value: s.share ? 'on' : 'off (sandbox config set accounts.' + s.kind + '.share true)',
145
+ value: s.share ? 'on' : 'off',
145
146
  tone: s.share ? 'ok' : 'muted',
146
- description: 'For sandboxes that use ' + s.usedBy.join(' or ') + '. ' + s.warnings.join(' '),
147
+ description: 'For sandboxes that use ' + s.usedFor + '. ' + s.warnings.join(' '),
147
148
  },
148
149
  {
149
150
  id: s.kind + ':state',
@@ -40,6 +40,7 @@ export declare const listServicesRun: import("../../kernel/define.js").Implement
40
40
  summary: import("zod").ZodNullable<import("zod").ZodString>;
41
41
  heldBy: import("zod").ZodNullable<import("zod").ZodString>;
42
42
  usedBy: import("zod").ZodArray<import("zod").ZodString>;
43
+ usedFor: import("zod").ZodString;
43
44
  warnings: import("zod").ZodArray<import("zod").ZodString>;
44
45
  canImport: import("zod").ZodBoolean;
45
46
  canLogin: import("zod").ZodBoolean;
@@ -4,9 +4,9 @@
4
4
  import fs from 'node:fs';
5
5
  import path from 'node:path';
6
6
  import { requireOnPc } from '../../../cli/commands/context.js';
7
- import { fail, safeText } from '../../../core/util/index.js';
7
+ import { fail, failWith, safeText } from '../../../core/util/index.js';
8
8
  import { AccountLeases, forgetEverywhere, HOST_SOURCES, pcEnv, ServiceAccountStore, } from '../../../host/accounts/index.js';
9
- import { isServiceKind, SERVICE_KINDS, SERVICE_SPECS, } from '../../../shared/accounts/index.js';
9
+ import { isServiceKind, SERVICE_KINDS, SERVICE_SPECS, usedByText, } from '../../../shared/accounts/index.js';
10
10
  import { readBoundedFile } from '../../../shared/io/index.js';
11
11
  import { implement } from '../../context.js';
12
12
  import { cancelled } from '../../kernel/index.js';
@@ -29,6 +29,7 @@ export function serviceRow(kind, config, store, leases) {
29
29
  summary: info?.summary ? safeText(info.summary) : null,
30
30
  heldBy: holder ? safeText(holder.dataSet) : null,
31
31
  usedBy: [...spec.usedBy],
32
+ usedFor: usedByText(spec.usedBy),
32
33
  warnings: [...spec.warnings],
33
34
  canImport: Boolean(source.fromPc || source.fromFile),
34
35
  canLogin: Boolean(source.fromAnswers),
@@ -55,10 +56,10 @@ async function kindOf(io, given, verb, offered = () => true) {
55
56
  cancelled();
56
57
  return picked;
57
58
  }
58
- /** Asks for the kind's fields; optional ones may stay empty. */
59
- async function askFields(io, spec) {
59
+ /** Asks for the kind's fields (those for typing it, or for a file); optional ones may stay empty. */
60
+ async function askFields(io, spec, mode) {
60
61
  const answers = {};
61
- for (const field of spec.fields) {
62
+ for (const field of spec.fields.filter((f) => !f.only || f.only === mode)) {
62
63
  const validate = (value) => {
63
64
  const v = value.trim();
64
65
  if (!v)
@@ -79,18 +80,31 @@ async function askFields(io, spec) {
79
80
  }
80
81
  return answers;
81
82
  }
83
+ /** A kind that only ever comes from a sandbox (Comet): why it cannot be taken from this PC, and what to do instead. */
84
+ function refuseSandboxOnly(spec) {
85
+ if (spec.sources.length !== 1 || spec.sources[0] !== 'sandbox')
86
+ return;
87
+ fail('Your ' + spec.label + " sign-in can't be copied from this PC: Windows locks it to your PC account.", 'Sign in once inside a sandbox (with accounts.' + spec.kind + '.share on): it is kept for the next ones.');
88
+ }
82
89
  function savedMessage(kind, share) {
83
90
  return ('Saved your ' +
84
91
  SERVICE_SPECS[kind].label +
85
92
  ' sign-in (encrypted for your Windows user).' +
86
- (share ? '' : ' Sandboxes get it once you share it: sandbox config set accounts.' + kind + '.share true'));
93
+ (share ? '' : ' Sandboxes get it once you turn on Share with sandboxes.'));
87
94
  }
88
95
  /** Saves a kind's sign-in from this PC's program or from a file, after a confirmation (--yes answers it). */
89
96
  export async function importServiceFlow(io, kind, from, deps) {
90
97
  const spec = SERVICE_SPECS[kind];
91
98
  const source = HOST_SOURCES[kind];
92
99
  if (!source.fromPc && !source.fromFile)
93
- fail(spec.label + ' cannot be imported.', 'Type it instead: sandbox account login ' + kind);
100
+ refuseSandboxOnly(spec);
101
+ if (!source.fromPc && !source.fromFile)
102
+ failWith(spec.label + ' cannot be imported.', 'Type it instead.', {
103
+ op: 'accounts.service.login',
104
+ input: { name: kind },
105
+ label: 'Sign in…',
106
+ cli: 'sandbox account login ' + kind,
107
+ });
94
108
  let file = from === undefined ? undefined : path.resolve(from);
95
109
  const isFile = (p) => {
96
110
  try {
@@ -120,10 +134,11 @@ export async function importServiceFlow(io, kind, from, deps) {
120
134
  let payload;
121
135
  let saved;
122
136
  if (useFile) {
123
- const bytes = readBoundedFile(file, spec.maxBytes);
137
+ const maxBytes = spec.maxFileBytes ?? spec.maxBytes;
138
+ const bytes = readBoundedFile(file, maxBytes);
124
139
  if (!bytes)
125
- fail('Cannot read ' + file + ' (missing, a link, or bigger than ' + spec.maxBytes / 1024 + ' KB).');
126
- payload = source.fromFile(bytes, await askFields(io, spec));
140
+ fail('Cannot read ' + file + ' (missing, a link, or bigger than ' + maxBytes / 1024 + ' KB).');
141
+ payload = source.fromFile(bytes, await askFields(io, spec, 'file'));
127
142
  saved = 'file';
128
143
  }
129
144
  else {
@@ -136,7 +151,11 @@ export async function importServiceFlow(io, kind, from, deps) {
136
151
  spec.label +
137
152
  ' sign-in found on this PC' +
138
153
  (file ? ' in ' + file : '') +
139
- (spec.returns ? ' (sign in there first, or sign in once inside a sandbox).' : '.'),
154
+ (spec.returns
155
+ ? ' (sign in there first, or sign in once inside a sandbox).'
156
+ : kind === 'perplexity'
157
+ ? ' (PERPLEXITY_API_KEY is not set for your Windows user: import a .env file, or type the key).'
158
+ : '.'),
140
159
  };
141
160
  deps.store.save(kind, payload, saved, source.summary(payload));
142
161
  for (const w of spec.warnings)
@@ -148,10 +167,17 @@ export async function loginServiceFlow(io, kind, deps) {
148
167
  const spec = SERVICE_SPECS[kind];
149
168
  const source = HOST_SOURCES[kind];
150
169
  if (!source.fromAnswers)
151
- fail(spec.label + ' has nothing to type.', spec.sources.includes('sandbox')
152
- ? 'Sign in once inside a sandbox (it is kept), or: sandbox account import ' + kind
153
- : 'Run: sandbox account import ' + kind + ' --from <file>');
154
- const payload = source.fromAnswers(await askFields(io, spec));
170
+ refuseSandboxOnly(spec);
171
+ if (!source.fromAnswers)
172
+ failWith(spec.label + ' has nothing to type.', spec.sources.includes('sandbox')
173
+ ? 'Sign in once inside a sandbox (it is kept), or import it.'
174
+ : 'Import it from a file.', {
175
+ op: 'accounts.service.import',
176
+ input: { name: kind },
177
+ label: 'Import…',
178
+ cli: 'sandbox account import ' + kind + (spec.sources.includes('sandbox') ? '' : ' --from <file>'),
179
+ });
180
+ const payload = source.fromAnswers(await askFields(io, spec, 'typed'));
155
181
  deps.store.save(kind, payload, 'typed', source.summary(payload));
156
182
  for (const w of spec.warnings)
157
183
  io.log(w, 'warn');
@@ -425,9 +425,9 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
425
425
  cwd: import("zod").ZodString;
426
426
  project: import("zod").ZodOptional<import("zod").ZodString>;
427
427
  phase: import("zod").ZodEnum<{
428
+ running: "running";
428
429
  failed: "failed";
429
430
  starting: "starting";
430
- running: "running";
431
431
  exited: "exited";
432
432
  }>;
433
433
  message: import("zod").ZodString;
@@ -582,6 +582,7 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
582
582
  summary: import("zod").ZodNullable<import("zod").ZodString>;
583
583
  heldBy: import("zod").ZodNullable<import("zod").ZodString>;
584
584
  usedBy: import("zod").ZodArray<import("zod").ZodString>;
585
+ usedFor: import("zod").ZodString;
585
586
  warnings: import("zod").ZodArray<import("zod").ZodString>;
586
587
  canImport: import("zod").ZodBoolean;
587
588
  canLogin: import("zod").ZodBoolean;
@@ -1028,6 +1029,11 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
1028
1029
  classic: "classic";
1029
1030
  }>>;
1030
1031
  savedAt: import("zod").ZodNullable<import("zod").ZodString>;
1032
+ login: import("zod").ZodNullable<import("zod").ZodString>;
1033
+ expiresAt: import("zod").ZodNullable<import("zod").ZodString>;
1034
+ repoCount: import("zod").ZodNullable<import("zod").ZodNumber>;
1035
+ checkedAt: import("zod").ZodNullable<import("zod").ZodString>;
1036
+ tokenUrl: import("zod").ZodString;
1031
1037
  }, import("zod/v4/core").$strip>, "github.status">, QueryDef<import("zod").ZodObject<{
1032
1038
  name: import("zod").ZodOptional<import("zod").ZodString>;
1033
1039
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
@@ -1045,6 +1051,7 @@ export declare const QUERIES: readonly [QueryDef<import("zod").ZodObject<{}, imp
1045
1051
  summary: import("zod").ZodNullable<import("zod").ZodString>;
1046
1052
  heldBy: import("zod").ZodNullable<import("zod").ZodString>;
1047
1053
  usedBy: import("zod").ZodArray<import("zod").ZodString>;
1054
+ usedFor: import("zod").ZodString;
1048
1055
  warnings: import("zod").ZodArray<import("zod").ZodString>;
1049
1056
  canImport: import("zod").ZodBoolean;
1050
1057
  canLogin: import("zod").ZodBoolean;
@@ -1181,9 +1188,9 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1181
1188
  cwd: import("zod").ZodString;
1182
1189
  project: import("zod").ZodOptional<import("zod").ZodString>;
1183
1190
  phase: import("zod").ZodEnum<{
1191
+ running: "running";
1184
1192
  failed: "failed";
1185
1193
  starting: "starting";
1186
- running: "running";
1187
1194
  exited: "exited";
1188
1195
  }>;
1189
1196
  message: import("zod").ZodString;
@@ -1333,6 +1340,7 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1333
1340
  summary: import("zod").ZodNullable<import("zod").ZodString>;
1334
1341
  heldBy: import("zod").ZodNullable<import("zod").ZodString>;
1335
1342
  usedBy: import("zod").ZodArray<import("zod").ZodString>;
1343
+ usedFor: import("zod").ZodString;
1336
1344
  warnings: import("zod").ZodArray<import("zod").ZodString>;
1337
1345
  canImport: import("zod").ZodBoolean;
1338
1346
  canLogin: import("zod").ZodBoolean;
@@ -1357,6 +1365,7 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1357
1365
  summary: import("zod").ZodNullable<import("zod").ZodString>;
1358
1366
  heldBy: import("zod").ZodNullable<import("zod").ZodString>;
1359
1367
  usedBy: import("zod").ZodArray<import("zod").ZodString>;
1368
+ usedFor: import("zod").ZodString;
1360
1369
  warnings: import("zod").ZodArray<import("zod").ZodString>;
1361
1370
  canImport: import("zod").ZodBoolean;
1362
1371
  canLogin: import("zod").ZodBoolean;
@@ -1364,6 +1373,29 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1364
1373
  ready: import("zod").ZodBoolean;
1365
1374
  }, import("zod/v4/core").$strip>>;
1366
1375
  }, import("zod/v4/core").$strip>, "accounts.services">;
1376
+ github: QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
1377
+ shareToken: import("zod").ZodBoolean;
1378
+ gitAccess: import("zod").ZodEnum<{
1379
+ readonly: "readonly";
1380
+ none: "none";
1381
+ full: "full";
1382
+ }>;
1383
+ token: import("zod").ZodEnum<{
1384
+ none: "none";
1385
+ saved: "saved";
1386
+ unreadable: "unreadable";
1387
+ }>;
1388
+ kind: import("zod").ZodNullable<import("zod").ZodEnum<{
1389
+ "fine-grained": "fine-grained";
1390
+ classic: "classic";
1391
+ }>>;
1392
+ savedAt: import("zod").ZodNullable<import("zod").ZodString>;
1393
+ login: import("zod").ZodNullable<import("zod").ZodString>;
1394
+ expiresAt: import("zod").ZodNullable<import("zod").ZodString>;
1395
+ repoCount: import("zod").ZodNullable<import("zod").ZodNumber>;
1396
+ checkedAt: import("zod").ZodNullable<import("zod").ZodString>;
1397
+ tokenUrl: import("zod").ZodString;
1398
+ }, import("zod/v4/core").$strip>, "github.status">;
1367
1399
  }, Record<string, never>, "accounts">, import("../kernel/define.js").ViewDef<{
1368
1400
  apps: QueryDef<import("zod").ZodObject<{
1369
1401
  scope: import("zod").ZodDefault<import("zod").ZodEnum<{
@@ -1799,6 +1831,11 @@ export declare const VIEWS: readonly [import("../kernel/define.js").ViewDef<{
1799
1831
  classic: "classic";
1800
1832
  }>>;
1801
1833
  savedAt: import("zod").ZodNullable<import("zod").ZodString>;
1834
+ login: import("zod").ZodNullable<import("zod").ZodString>;
1835
+ expiresAt: import("zod").ZodNullable<import("zod").ZodString>;
1836
+ repoCount: import("zod").ZodNullable<import("zod").ZodNumber>;
1837
+ checkedAt: import("zod").ZodNullable<import("zod").ZodString>;
1838
+ tokenUrl: import("zod").ZodString;
1802
1839
  }, import("zod/v4/core").$strip>, "github.status">;
1803
1840
  }, Record<string, never>, "github">, import("../kernel/define.js").ViewDef<{
1804
1841
  status: QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
@@ -72,6 +72,6 @@ export const cleanEngineRun = implement(cleanEngine, async (ctx, _input, io) =>
72
72
  const stopped = results.filter((r) => r.stopped).length;
73
73
  const failed = results.length - stopped;
74
74
  if (failed)
75
- fail(plural(failed, 'HCS system') + ' could not be stopped.', 'Run it again from an administrator terminal: sandbox engine clean');
75
+ fail(plural(failed, 'HCS system') + ' could not be stopped.', 'Stopping them needs administrator rights: start the menu from an administrator terminal and try again.');
76
76
  return { available: true, stopped, failed, message: 'Stopped ' + plural(stopped, 'HCS system') + '.' };
77
77
  });