windows-development-sandbox 1.9.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 (398) hide show
  1. package/README.md +64 -17
  2. package/config.example.json +7 -2
  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 +23 -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 -88
  149. package/dist/cli/commands/web.d.ts +7 -1
  150. package/dist/cli/commands/web.js +45 -71
  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 +3 -2
  200. package/dist/core/schema/config.d.ts +6 -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/schema/vpn.js +1 -1
  211. package/dist/core/schema/web.d.ts +1 -0
  212. package/dist/core/schema/web.js +4 -1
  213. package/dist/core/types.d.ts +6 -3
  214. package/dist/guest/boot/boot.js +11 -1
  215. package/dist/guest/daemon/daemon.js +1 -1
  216. package/dist/guest/daemon/sessions.d.ts +3 -2
  217. package/dist/guest/daemon/sessions.js +38 -7
  218. package/dist/guest/governor/core.d.ts +44 -0
  219. package/dist/guest/governor/core.js +124 -0
  220. package/dist/guest/governor/decide.d.ts +53 -15
  221. package/dist/guest/governor/decide.js +155 -72
  222. package/dist/guest/governor/governor.d.ts +2 -35
  223. package/dist/guest/governor/governor.js +35 -99
  224. package/dist/guest/governor/index.d.ts +1 -0
  225. package/dist/guest/governor/index.js +1 -0
  226. package/dist/guest/network/firewall.d.ts +3 -0
  227. package/dist/guest/network/firewall.js +65 -23
  228. package/dist/guest/runtime/process.js +53 -5
  229. package/dist/guest/sessions/viewer.js +5 -1
  230. package/dist/guest/setup/claude-mem.js +12 -4
  231. package/dist/guest/setup/github-token.d.ts +7 -0
  232. package/dist/guest/setup/github-token.js +65 -0
  233. package/dist/guest/toolchains/languages/node.js +40 -4
  234. package/dist/guest/toolchains/native/rust-extras.js +2 -2
  235. package/dist/guest/toolchains/tools/cli.d.ts +8 -0
  236. package/dist/guest/toolchains/tools/cli.js +16 -2
  237. package/dist/guest/vpn/openvpn.d.ts +5 -0
  238. package/dist/guest/vpn/openvpn.js +14 -1
  239. package/dist/guest/vpn/vpn.js +55 -16
  240. package/dist/guest/vpn/wireguard.js +2 -0
  241. package/dist/host/channel/attach.d.ts +1 -0
  242. package/dist/host/channel/attach.js +1 -0
  243. package/dist/host/channel/channel.d.ts +1 -1
  244. package/dist/host/channel/channel.js +2 -2
  245. package/dist/host/engines/hcs/check.d.ts +1 -0
  246. package/dist/host/engines/hcs/check.js +1 -1
  247. package/dist/host/engines/hcs/engine.d.ts +1 -1
  248. package/dist/host/engines/hcs/engine.js +6 -4
  249. package/dist/host/engines/hcs/helper.d.ts +11 -0
  250. package/dist/host/engines/hcs/helper.js +31 -2
  251. package/dist/host/engines/hcs/leftovers.d.ts +42 -0
  252. package/dist/host/engines/hcs/leftovers.js +101 -0
  253. package/dist/host/engines/index.d.ts +1 -0
  254. package/dist/host/engines/index.js +1 -0
  255. package/dist/host/github/deliver.d.ts +13 -0
  256. package/dist/host/github/deliver.js +51 -0
  257. package/dist/host/github/index.d.ts +2 -0
  258. package/dist/host/github/index.js +3 -0
  259. package/dist/host/github/token.d.ts +21 -0
  260. package/dist/host/github/token.js +74 -0
  261. package/dist/host/launch/generate.js +11 -5
  262. package/dist/host/launch/index.d.ts +1 -1
  263. package/dist/host/launch/index.js +1 -1
  264. package/dist/host/launch/session-file.js +1 -2
  265. package/dist/host/launch/wsb-file.d.ts +11 -7
  266. package/dist/host/launch/wsb-file.js +30 -12
  267. package/dist/host/life/host-memory.d.ts +1 -0
  268. package/dist/host/life/host-memory.js +4 -1
  269. package/dist/host/life/watchdog.d.ts +11 -0
  270. package/dist/host/life/watchdog.js +36 -4
  271. package/dist/host/sandbox/tasklist.d.ts +6 -0
  272. package/dist/host/sandbox/tasklist.js +37 -0
  273. package/dist/host/secrets/launch-secrets.d.ts +2 -1
  274. package/dist/host/secrets/launch-secrets.js +4 -2
  275. package/dist/host/vpn/status.js +13 -3
  276. package/dist/host/web/backend.d.ts +1 -3
  277. package/dist/host/web/index.d.ts +2 -1
  278. package/dist/host/web/index.js +2 -1
  279. package/dist/host/web/live.d.ts +23 -0
  280. package/dist/host/web/live.js +107 -0
  281. package/dist/host/web/rpc.d.ts +6 -1
  282. package/dist/host/web/rpc.js +23 -31
  283. package/dist/host/web/runner.d.ts +4 -0
  284. package/dist/host/web/runner.js +12 -1
  285. package/dist/host/web/server.d.ts +30 -2
  286. package/dist/host/web/server.js +87 -29
  287. package/dist/host/web/state.d.ts +1 -0
  288. package/dist/host/web/state.js +2 -0
  289. package/dist/runtime/agent.js +44 -16
  290. package/dist/runtime/daemon.js +1154 -857
  291. package/dist/runtime/db.js +44 -16
  292. package/dist/runtime/main.js +532 -115
  293. package/dist/runtime/netproxy.js +34 -9
  294. package/dist/runtime/view.js +499 -149
  295. package/dist/selftest/app.test.js +620 -12
  296. package/dist/selftest/channel.test.js +18 -1
  297. package/dist/selftest/cli.test.js +1 -1
  298. package/dist/selftest/config.test.js +1 -1
  299. package/dist/selftest/contained.test.js +1 -1
  300. package/dist/selftest/data.test.js +1 -2
  301. package/dist/selftest/engine.test.js +3 -1
  302. package/dist/selftest/github.test.d.ts +2 -0
  303. package/dist/selftest/github.test.js +243 -0
  304. package/dist/selftest/guest-boot.test.js +47 -1
  305. package/dist/selftest/hcs.test.js +105 -8
  306. package/dist/selftest/health.test.js +71 -0
  307. package/dist/selftest/heavy-load.test.js +152 -66
  308. package/dist/selftest/index.js +4 -0
  309. package/dist/selftest/layout.test.js +8 -0
  310. package/dist/selftest/live-terminal.test.js +74 -0
  311. package/dist/selftest/menu-screens.js +171 -56
  312. package/dist/selftest/menu.test.js +54 -37
  313. package/dist/selftest/migrate.test.js +14 -12
  314. package/dist/selftest/network.test.js +20 -1
  315. package/dist/selftest/powershell-variables.test.d.ts +2 -0
  316. package/dist/selftest/powershell-variables.test.js +61 -0
  317. package/dist/selftest/support/engine-golden.js +1 -0
  318. package/dist/selftest/support/fixtures.d.ts +5 -0
  319. package/dist/selftest/support/web-preview.d.ts +1 -0
  320. package/dist/selftest/support/web-preview.js +856 -0
  321. package/dist/selftest/update-service.test.js +15 -8
  322. package/dist/selftest/vpn.test.js +86 -2
  323. package/dist/selftest/web.test.js +58 -11
  324. package/dist/shared/channel/run-dir.d.ts +2 -0
  325. package/dist/shared/channel/run-dir.js +3 -0
  326. package/dist/shared/channel/schema.d.ts +7 -0
  327. package/dist/shared/channel/schema.js +9 -1
  328. package/dist/shared/channel/secrets.d.ts +1 -0
  329. package/dist/shared/channel/secrets.js +3 -0
  330. package/dist/shared/github/index.d.ts +1 -0
  331. package/dist/shared/github/index.js +2 -0
  332. package/dist/shared/github/token.d.ts +29 -0
  333. package/dist/shared/github/token.js +89 -0
  334. package/dist/shared/io/copy-tree.d.ts +7 -0
  335. package/dist/shared/io/copy-tree.js +45 -0
  336. package/dist/shared/io/index.d.ts +2 -0
  337. package/dist/shared/io/index.js +2 -0
  338. package/dist/shared/io/robocopy-result.d.ts +6 -0
  339. package/dist/shared/io/robocopy-result.js +23 -0
  340. package/dist/shared/memory/policy.d.ts +38 -12
  341. package/dist/shared/memory/policy.js +58 -19
  342. package/dist/shared/network/firewall-rules.d.ts +8 -0
  343. package/dist/shared/network/firewall-rules.js +28 -0
  344. package/dist/shared/pty/ctrl-c.d.ts +18 -0
  345. package/dist/shared/pty/ctrl-c.js +36 -0
  346. package/dist/shared/pty/index.d.ts +1 -0
  347. package/dist/shared/pty/index.js +1 -0
  348. package/dist/shared/pty/terminal.d.ts +2 -0
  349. package/dist/shared/pty/terminal.js +21 -2
  350. package/dist/shared/vpn/kill-switch.d.ts +13 -2
  351. package/dist/shared/vpn/kill-switch.js +88 -8
  352. package/dist/shared/web/protocol.d.ts +0 -4
  353. package/dist/sync/watcher.js +1 -1
  354. package/dist/web/index.html +2 -2
  355. package/dist/web/{main-T5DMCHYV.css → main-6JF3ASB5.css} +1 -1
  356. package/dist/web/main-Z645W45E.js +219 -0
  357. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  358. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  359. package/native/csharp/HostTools/MemoryStatus.cs +128 -107
  360. package/native/scripts/memory-status.ps1 +10 -2
  361. package/package.json +10 -3
  362. package/sandbox/csharp/MemGov.cs +668 -398
  363. package/sandbox/csharp/PtyHost.cs +104 -15
  364. package/sandbox/csharp/SandboxTools/CpuCap.cs +50 -1
  365. package/sandbox/csharp/SandboxTools/Program.cs +1 -1
  366. package/sandbox/scripts/new-shortcuts.ps1 +3 -1
  367. package/sandbox/scripts/repair-wmi-services.ps1 +26 -0
  368. package/schemas/config.schema.json +25 -7
  369. package/schemas/sandbox-config.schema.json +7 -3
  370. package/dist/cli/commands/accounts.d.ts +0 -2
  371. package/dist/cli/commands/accounts.js +0 -96
  372. package/dist/cli/commands/data/clean.d.ts +0 -3
  373. package/dist/cli/commands/data/clean.js +0 -60
  374. package/dist/cli/commands/data/index.d.ts +0 -4
  375. package/dist/cli/commands/data/index.js +0 -62
  376. package/dist/cli/commands/maintenance/clean.d.ts +0 -2
  377. package/dist/cli/commands/maintenance/clean.js +0 -24
  378. package/dist/cli/commands/maintenance/config-share.d.ts +0 -12
  379. package/dist/cli/commands/maintenance/config-share.js +0 -80
  380. package/dist/cli/commands/projects/projects.d.ts +0 -2
  381. package/dist/cli/commands/projects/projects.js +0 -162
  382. package/dist/cli/commands/storage/contained.d.ts +0 -3
  383. package/dist/cli/commands/storage/contained.js +0 -179
  384. package/dist/cli/commands/storage/storage.d.ts +0 -8
  385. package/dist/cli/commands/storage/storage.js +0 -179
  386. package/dist/cli/menu/add-agent.d.ts +0 -47
  387. package/dist/cli/menu/add-agent.js +0 -168
  388. package/dist/cli/menu/apps.d.ts +0 -69
  389. package/dist/cli/menu/apps.js +0 -214
  390. package/dist/cli/menu/data-folder.d.ts +0 -18
  391. package/dist/cli/menu/data-folder.js +0 -99
  392. package/dist/cli/menu/share-settings.d.ts +0 -21
  393. package/dist/cli/menu/share-settings.js +0 -112
  394. package/dist/cli/menu/vpn-login.d.ts +0 -16
  395. package/dist/cli/menu/vpn-login.js +0 -74
  396. package/dist/web/main-NRRS5O6Z.js +0 -157
  397. /package/dist/cli/{commands/data/collect.d.ts → services/data-collect.d.ts} +0 -0
  398. /package/dist/cli/{commands/data/remove.d.ts → services/data-remove.d.ts} +0 -0
@@ -0,0 +1,125 @@
1
+ // The accounts feature's work: the saved logins of each agent, and saving, using, defaulting, renaming and removing
2
+ // them (through AccountsService). Talks only through io; prints nothing. Emails and the sandbox's own words go through
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';
5
+ import { AccountsService } from '../../../cli/services/index.js';
6
+ import { implement } from '../../context.js';
7
+ import { cancelled } from '../../kernel/index.js';
8
+ import { defaultAccount, listAccounts, NAME_RULE, removeAccount, renameAccount, saveAccount, useAccount, } from './accounts.def.js';
9
+ const NAME = /^[A-Za-z0-9_-]{1,40}$/;
10
+ const validName = (v) => NAME.test(v.trim()) || NAME_RULE;
11
+ /** "work" (me@example.com) as the notices and the command line have always said it. */
12
+ function label(a) {
13
+ return safeText('"' + a.name + '"' + (a.email ? ' (' + a.email + ')' : ''));
14
+ }
15
+ /** The saved logins of a kept agent; none when its folder cannot be read (the other agents still list). */
16
+ function savedLogins(service, agent) {
17
+ try {
18
+ return service.list(agent).map((r) => ({
19
+ name: r.name,
20
+ email: r.email === null ? null : safeText(r.email),
21
+ isDefault: r.isDefault,
22
+ isActive: r.isActive,
23
+ savedAt: r.savedAt,
24
+ }));
25
+ }
26
+ catch {
27
+ // The menu has always shown such an agent with no logins; the command line says so too.
28
+ return [];
29
+ }
30
+ }
31
+ /**
32
+ * The account an operation is about: the name given, else asked. Saving asks for a new name; the others pick one of
33
+ * the saved logins (none saved: the fix is to save one).
34
+ */
35
+ async function accountName(io, service, verb, agent, given) {
36
+ if (given !== undefined)
37
+ return verb === 'save' ? given.trim() : given;
38
+ if (verb === 'save') {
39
+ const typed = await io.text({ title: 'Name for this login:', validate: validName });
40
+ if (typed === undefined)
41
+ cancelled();
42
+ return typed.trim();
43
+ }
44
+ const rows = service.list(agent);
45
+ if (!rows.length)
46
+ fail('No saved accounts.', 'Sign in inside the sandbox, then run: sandbox account save <name>');
47
+ const picked = await io.choose({
48
+ title: 'Which account?',
49
+ choices: rows.map((a) => ({ value: a.name, label: label(a) })),
50
+ });
51
+ if (picked === undefined)
52
+ cancelled();
53
+ return picked;
54
+ }
55
+ export const listAccountsRun = implement(listAccounts, async (ctx, input) => {
56
+ const service = new AccountsService(ctx);
57
+ const agents = service.agents().map((a) => ({
58
+ name: a.name,
59
+ kept: a.kept,
60
+ canSavePc: a.canSavePc,
61
+ accounts: a.kept ? savedLogins(service, a.name) : [],
62
+ }));
63
+ // An agent that keeps no login, or no such agent: the command line says why (the store's own message).
64
+ if (!agents.some((a) => a.name === input.agent && a.kept))
65
+ service.list(input.agent);
66
+ return { agent: input.agent, agents };
67
+ });
68
+ export const saveAccountRun = implement(saveAccount, async (ctx, input, io) => {
69
+ const service = new AccountsService(ctx);
70
+ const name = await accountName(io, service, 'save', input.agent, input.name);
71
+ const saved = service.save(name, input.fromHost, input.agent);
72
+ return { name: saved.name, message: 'Saved account ' + label(saved) + '.' };
73
+ });
74
+ export const useAccountRun = implement(useAccount, async (ctx, input, io) => {
75
+ const service = new AccountsService(ctx);
76
+ const name = await accountName(io, service, 'use', input.agent, input.name);
77
+ // The switch is done before the question: a "no" to the restart keeps the new login and only skips the restart.
78
+ const used = service.activate(name, input.agent);
79
+ const lines = ['Sandbox now uses ' + label(used) + '.'];
80
+ if (used.note)
81
+ lines.push(safeText(used.note));
82
+ if (service.hasRunningSessions(input.agent) && !input.noRestart) {
83
+ const restart = await io.confirm({
84
+ title: 'Restart the running ' + input.agent + ' sessions?',
85
+ lines: ['They restart and continue their conversation where the agent can, now under the new login.'],
86
+ yes: 'Restart',
87
+ implied: true,
88
+ });
89
+ if (restart)
90
+ lines.push(safeText(await service.restart(input.agent)) +
91
+ ' with --continue; the conversation carries on under the new account.');
92
+ }
93
+ return { lines };
94
+ });
95
+ export const defaultAccountRun = implement(defaultAccount, async (ctx, input, io) => {
96
+ const service = new AccountsService(ctx);
97
+ const name = await accountName(io, service, 'default', input.agent, input.name);
98
+ service.setDefault(name, input.agent);
99
+ return { message: 'Default account: ' + name };
100
+ });
101
+ export const renameAccountRun = implement(renameAccount, async (ctx, input, io) => {
102
+ const service = new AccountsService(ctx);
103
+ const name = await accountName(io, service, 'rename', input.agent, input.name);
104
+ const typed = input.to ?? (await io.text({ title: 'New name for "' + name + '":', initial: name, validate: validName }));
105
+ const to = typed?.trim();
106
+ if (to === undefined || to === name)
107
+ cancelled();
108
+ service.rename(name, to, input.agent);
109
+ return { message: 'Renamed account ' + name + ' to ' + to + '.' };
110
+ });
111
+ export const removeAccountRun = implement(removeAccount, async (ctx, input, io) => {
112
+ const service = new AccountsService(ctx);
113
+ const name = await accountName(io, service, 'remove', input.agent, input.name);
114
+ const yes = await io.confirm({
115
+ title: 'Remove the saved account "' + name + '"?',
116
+ lines: ['Its login cannot be recovered; you would sign in again.'],
117
+ yes: 'Remove',
118
+ danger: true,
119
+ noTerminal: { message: 'Cannot ask here (no terminal).', fix: 'Add --yes to remove it without asking.' },
120
+ });
121
+ if (!yes)
122
+ cancelled('Nothing removed.');
123
+ service.remove(name, input.agent);
124
+ return { message: 'Removed account ' + name + '.' };
125
+ });
@@ -0,0 +1,2 @@
1
+ export * from './accounts.def.js';
2
+ export * from './accounts.run.js';
@@ -0,0 +1,3 @@
1
+ // The accounts feature: the saved logins of each agent, and saving, using, defaulting, renaming and removing them.
2
+ export * from './accounts.def.js';
3
+ export * from './accounts.run.js';
@@ -0,0 +1,17 @@
1
+ import type { Harness } from '../../../core/types.js';
2
+ /** How a new agent gets into the sandbox. */
3
+ export type AgentSource = 'npm' | 'uv' | 'host';
4
+ /** Nothing wrong with the name (true), or what is wrong. Pure. */
5
+ export declare function agentNameProblem(name: string, taken: readonly string[]): true | string;
6
+ /** The command a package usually provides: "@scope/my-agent@latest" gives "my-agent". Pure. */
7
+ export declare function commandFromPackage(pkg: string): string;
8
+ /** The config entry for a new agent. Pure. */
9
+ export declare function newAgent(source: AgentSource, what: string, command: string, hostDir?: string): Harness;
10
+ /** The entry of an agent, checked the way the config file checks it. Returns the entry or what is wrong. */
11
+ export declare function checkedAgent(harness: Harness): Harness | string;
12
+ /** What `harnesses` should say with `name` added. Pure. */
13
+ export declare function withAgent(current: unknown, name: string, harness: Harness): Record<string, unknown>;
14
+ /** What `harnesses` should say with `name` taken out. Pure. */
15
+ export declare function withoutAgent(current: unknown, name: string): Record<string, unknown>;
16
+ /** The agents of `names` that are not built in (only these can be removed). Pure. */
17
+ export declare function addedAgents(names: readonly string[]): string[];
@@ -0,0 +1,50 @@
1
+ // Agents as entries of `harnesses` in your settings: their names, the entry a new agent gets, and the lists that
2
+ // adding and removing one change. Node side (it checks names with the config schema); the agents run writes them.
3
+ import { DEFAULTS } from '../../../core/config/index.js';
4
+ import { HarnessSchema, NameSchema, describeIssues } from '../../../core/schema/index.js';
5
+ /** Nothing wrong with the name (true), or what is wrong. Pure. */
6
+ export function agentNameProblem(name, taken) {
7
+ const typed = name.trim();
8
+ if (!typed)
9
+ return 'Type a name.';
10
+ const parsed = NameSchema.safeParse(typed);
11
+ if (!parsed.success)
12
+ return 'Use letters, numbers, - and _ only.';
13
+ if (taken.some((t) => t.toLowerCase() === typed.toLowerCase()))
14
+ return typed + ' is an agent already.';
15
+ return true;
16
+ }
17
+ /** The command a package usually provides: "@scope/my-agent@latest" gives "my-agent". Pure. */
18
+ export function commandFromPackage(pkg) {
19
+ const version = pkg.lastIndexOf('@');
20
+ const bare = version > 0 ? pkg.slice(0, version) : pkg;
21
+ return (bare.split(/[\\/]/).pop() ?? '').replace(/[^A-Za-z0-9._-]/g, '');
22
+ }
23
+ /** The config entry for a new agent. Pure. */
24
+ export function newAgent(source, what, command, hostDir = 'auto') {
25
+ const common = { arguments: [], environment: {} };
26
+ if (source === 'npm')
27
+ return { ...common, npmPackage: what, npmBin: command };
28
+ if (source === 'uv')
29
+ return { ...common, uvPackage: what, uvBin: command };
30
+ return { ...common, hostExecutable: what, hostDir };
31
+ }
32
+ /** The entry of an agent, checked the way the config file checks it. Returns the entry or what is wrong. */
33
+ export function checkedAgent(harness) {
34
+ const checked = HarnessSchema.safeParse(harness);
35
+ return checked.success ? harness : describeIssues(checked.error).join('; ');
36
+ }
37
+ /** What `harnesses` should say with `name` added. Pure. */
38
+ export function withAgent(current, name, harness) {
39
+ return { ...(current && typeof current === 'object' ? current : {}), [name]: harness };
40
+ }
41
+ /** What `harnesses` should say with `name` taken out. Pure. */
42
+ export function withoutAgent(current, name) {
43
+ const rest = { ...(current && typeof current === 'object' ? current : {}) };
44
+ delete rest[name];
45
+ return rest;
46
+ }
47
+ /** The agents of `names` that are not built in (only these can be removed). Pure. */
48
+ export function addedAgents(names) {
49
+ return names.filter((n) => !(n in DEFAULTS.harnesses));
50
+ }
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod';
2
+ import { type Page } from '../../kernel/index.js';
3
+ export declare const AgentRowSchema: z.ZodObject<{
4
+ name: z.ZodString;
5
+ ready: z.ZodBoolean;
6
+ isDefault: z.ZodBoolean;
7
+ removable: z.ZodBoolean;
8
+ }, z.core.$strip>;
9
+ export type AgentRow = z.output<typeof AgentRowSchema>;
10
+ export declare const AgentsListSchema: z.ZodObject<{
11
+ folder: z.ZodString;
12
+ defaultAgent: z.ZodString;
13
+ agents: z.ZodArray<z.ZodObject<{
14
+ name: z.ZodString;
15
+ ready: z.ZodBoolean;
16
+ isDefault: z.ZodBoolean;
17
+ removable: z.ZodBoolean;
18
+ }, z.core.$strip>>;
19
+ }, z.core.$strip>;
20
+ export type AgentsList = z.output<typeof AgentsListSchema>;
21
+ export declare const listAgents: import("../../kernel/define.js").QueryDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
22
+ folder: z.ZodString;
23
+ defaultAgent: z.ZodString;
24
+ agents: z.ZodArray<z.ZodObject<{
25
+ name: z.ZodString;
26
+ ready: z.ZodBoolean;
27
+ isDefault: z.ZodBoolean;
28
+ removable: z.ZodBoolean;
29
+ }, z.core.$strip>>;
30
+ }, z.core.$strip>, "agents.list">;
31
+ export declare const startAgent: import("../../kernel/define.js").OperationDef<z.ZodObject<{
32
+ agent: z.ZodString;
33
+ project: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strip>, z.ZodObject<{
35
+ session: z.ZodString;
36
+ message: z.ZodString;
37
+ }, z.core.$strip>, "agents.start">;
38
+ export declare const addAgent: import("../../kernel/define.js").OperationDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
39
+ name: z.ZodString;
40
+ message: z.ZodString;
41
+ }, z.core.$strip>, "agents.add">;
42
+ export declare const makeDefaultAgent: import("../../kernel/define.js").OperationDef<z.ZodObject<{
43
+ name: z.ZodString;
44
+ }, z.core.$strip>, z.ZodObject<{
45
+ message: z.ZodString;
46
+ }, z.core.$strip>, "agents.makeDefault">;
47
+ export declare const removeAgent: import("../../kernel/define.js").OperationDef<z.ZodObject<{
48
+ name: z.ZodString;
49
+ }, z.core.$strip>, z.ZodObject<{
50
+ message: z.ZodString;
51
+ }, z.core.$strip>, "agents.remove">;
52
+ /** The agents page: the default agent first, then the others, then "Add an agent…" (ids `agent:<name>` and `add`). */
53
+ export declare function agentsPage(o: AgentsList): Page;
54
+ export declare const agentsView: import("../../kernel/define.js").ViewDef<{
55
+ agents: import("../../kernel/define.js").QueryDef<z.ZodObject<{}, z.core.$strip>, z.ZodObject<{
56
+ folder: z.ZodString;
57
+ defaultAgent: z.ZodString;
58
+ agents: z.ZodArray<z.ZodObject<{
59
+ name: z.ZodString;
60
+ ready: z.ZodBoolean;
61
+ isDefault: z.ZodBoolean;
62
+ removable: z.ZodBoolean;
63
+ }, z.core.$strip>>;
64
+ }, z.core.$strip>, "agents.list">;
65
+ }, Record<string, never>, "agents">;
@@ -0,0 +1,142 @@
1
+ // The agents you can start: the list, starting one in a project of the running sandbox, adding one, making one the
2
+ // default and removing one you added. Pure: schemas, labels and the view; agents.run.ts does the work.
3
+ import { z } from 'zod';
4
+ import { action, defineOperation, defineQuery, defineView, link } from '../../kernel/index.js';
5
+ /** Agent and project names as the web UI has always accepted them. */
6
+ const NameText = z.string().regex(/^[A-Za-z0-9_.-]{1,64}$/);
7
+ export const AgentRowSchema = z.object({
8
+ name: z.string().describe('The agent'),
9
+ ready: z.boolean().describe('Installed in the sandbox already (starts without an install)'),
10
+ isDefault: z.boolean().describe('The agent that starts by default'),
11
+ removable: z.boolean().describe('You added it (built-in agents cannot be removed)'),
12
+ });
13
+ export const AgentsListSchema = z.object({
14
+ folder: z.string().describe('The folder a start works on (the current folder)'),
15
+ defaultAgent: z.string().describe('The default agent'),
16
+ agents: z.array(AgentRowSchema).describe('Every agent in your settings, built in or added'),
17
+ });
18
+ export const listAgents = defineQuery({
19
+ id: 'agents.list',
20
+ title: 'Agents',
21
+ summary: 'the agents you can start, and which one is the default',
22
+ input: z.object({}),
23
+ output: AgentsListSchema,
24
+ surfaces: { except: { cli: 'sandbox config list shows the agents (harnesses) and the default (defaultHarness)' } },
25
+ });
26
+ export const startAgent = defineOperation({
27
+ id: 'agents.start',
28
+ title: 'Start an agent',
29
+ summary: 'start an agent in a project of the running sandbox',
30
+ input: z.object({
31
+ agent: NameText.describe('The agent to start'),
32
+ project: NameText.optional().describe('The project of the running sandbox (asked when there are several)'),
33
+ }),
34
+ output: z.object({
35
+ session: z.string().describe('The new session'),
36
+ message: z.string().describe('What happened'),
37
+ }),
38
+ text: (o) => o.message,
39
+ surfaces: {
40
+ except: {
41
+ cli: 'sandbox <agent> and sandbox launch start agents on the command line (they boot the sandbox and can attach the terminal)',
42
+ menu: 'the menu starts agents with launch, which can boot the sandbox and attach this terminal',
43
+ },
44
+ },
45
+ });
46
+ export const addAgent = defineOperation({
47
+ id: 'agents.add',
48
+ title: 'Add an agent…',
49
+ summary: 'add an agent by its npm or Python package, or a program on this PC',
50
+ input: z.object({}),
51
+ output: z.object({ name: z.string().describe('The new agent'), message: z.string().describe('What happened') }),
52
+ text: (o) => o.message,
53
+ surfaces: { except: { cli: 'sandbox config set harnesses adds agents on the command line' } },
54
+ });
55
+ export const makeDefaultAgent = defineOperation({
56
+ id: 'agents.makeDefault',
57
+ title: 'Make default',
58
+ summary: 'make an agent the one that starts by default',
59
+ input: z.object({ name: z.string().describe('The agent') }),
60
+ output: z.object({ message: z.string().describe('What happened') }),
61
+ text: (o) => o.message,
62
+ surfaces: { except: { cli: 'sandbox config set defaultHarness <name> does this on the command line' } },
63
+ });
64
+ export const removeAgent = defineOperation({
65
+ id: 'agents.remove',
66
+ title: 'Remove',
67
+ summary: 'take an agent you added out of your settings',
68
+ input: z.object({ name: z.string().describe('The agent') }),
69
+ output: z.object({ message: z.string().describe('What happened') }),
70
+ danger: true,
71
+ text: (o) => o.message,
72
+ surfaces: { except: { cli: 'sandbox config set harnesses removes agents on the command line' } },
73
+ });
74
+ function folderName(folder) {
75
+ return folder.split(/[\\/]/).pop() ?? folder;
76
+ }
77
+ /** The description of an agent row: what a start does, and whether you can remove it. Pure. */
78
+ function agentDescription(a, where) {
79
+ const removing = a.removable
80
+ ? a.isDefault
81
+ ? ' You added it. Make another agent the default to remove it.'
82
+ : ' You added it.'
83
+ : '';
84
+ return 'Starts ' + a.name + ' in ' + where + '.' + (a.isDefault ? ' It is the default agent.' : '') + removing;
85
+ }
86
+ /** The menu's words for the remove key, on an agent you added that is not the default. */
87
+ function agentKeys(a) {
88
+ return a.removable && !a.isDefault ? 'x removes it.' : undefined;
89
+ }
90
+ function agentItem(a, where) {
91
+ return {
92
+ id: 'agent:' + a.name,
93
+ label: a.name,
94
+ hint: a.ready ? 'ready' : 'installs on first start',
95
+ tone: a.ready ? 'ok' : 'muted',
96
+ icon: a.name,
97
+ badges: a.isDefault ? [{ text: 'default', tone: 'accent' }] : [],
98
+ description: agentDescription(a, where),
99
+ keys: agentKeys(a),
100
+ primary: link({ kind: 'start-agent', agent: a.name }, 'Start ' + a.name, { verb: 'start' }),
101
+ actions: [
102
+ ...(a.isDefault
103
+ ? []
104
+ : [action(makeDefaultAgent, { name: a.name }, { key: 'd', verb: 'make default', importance: 1 })]),
105
+ ...(a.removable && !a.isDefault
106
+ ? [action(removeAgent, { name: a.name }, { key: 'x', verb: 'remove', importance: 1 })]
107
+ : []),
108
+ ],
109
+ };
110
+ }
111
+ /** The agents page: the default agent first, then the others, then "Add an agent…" (ids `agent:<name>` and `add`). */
112
+ export function agentsPage(o) {
113
+ const where = folderName(o.folder);
114
+ const sorted = [...o.agents].sort((a, b) => Number(b.isDefault) - Number(a.isDefault));
115
+ return {
116
+ title: 'Agents',
117
+ sections: [
118
+ {
119
+ id: 'start',
120
+ title: 'Start in ' + where,
121
+ cards: true,
122
+ items: [
123
+ ...sorted.map((a) => agentItem(a, where)),
124
+ {
125
+ id: 'add',
126
+ label: 'Add an agent…',
127
+ description: 'Add another agent by its npm or Python package, or a program on this PC. It is saved in your settings and appears in this list.',
128
+ primary: action(addAgent, {}, { verb: 'add' }),
129
+ },
130
+ ],
131
+ },
132
+ ],
133
+ };
134
+ }
135
+ export const agentsView = defineView({
136
+ id: 'agents',
137
+ title: 'Agents',
138
+ summary: 'The agents you can start: start one, add one, choose the default.',
139
+ queries: { agents: listAgents },
140
+ operations: [startAgent, addAgent, makeDefaultAgent, removeAgent],
141
+ build: ({ agents }) => agentsPage(agents),
142
+ });
@@ -0,0 +1,31 @@
1
+ export declare const listAgentsRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").QueryDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
2
+ folder: import("zod").ZodString;
3
+ defaultAgent: import("zod").ZodString;
4
+ agents: import("zod").ZodArray<import("zod").ZodObject<{
5
+ name: import("zod").ZodString;
6
+ ready: import("zod").ZodBoolean;
7
+ isDefault: import("zod").ZodBoolean;
8
+ removable: import("zod").ZodBoolean;
9
+ }, import("zod/v4/core").$strip>>;
10
+ }, import("zod/v4/core").$strip>, "agents.list">, import("../../../cli/commands/context.js").Context>;
11
+ export declare const startAgentRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
12
+ agent: import("zod").ZodString;
13
+ project: import("zod").ZodOptional<import("zod").ZodString>;
14
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
15
+ session: import("zod").ZodString;
16
+ message: import("zod").ZodString;
17
+ }, import("zod/v4/core").$strip>, "agents.start">, import("../../../cli/commands/context.js").Context>;
18
+ export declare const addAgentRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
19
+ name: import("zod").ZodString;
20
+ message: import("zod").ZodString;
21
+ }, import("zod/v4/core").$strip>, "agents.add">, import("../../../cli/commands/context.js").Context>;
22
+ export declare const makeDefaultAgentRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
23
+ name: import("zod").ZodString;
24
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
25
+ message: import("zod").ZodString;
26
+ }, import("zod/v4/core").$strip>, "agents.makeDefault">, import("../../../cli/commands/context.js").Context>;
27
+ export declare const removeAgentRun: import("../../kernel/define.js").Implementation<import("../../kernel/define.js").OperationDef<import("zod").ZodObject<{
28
+ name: import("zod").ZodString;
29
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
30
+ message: import("zod").ZodString;
31
+ }, import("zod/v4/core").$strip>, "agents.remove">, import("../../../cli/commands/context.js").Context>;
@@ -0,0 +1,189 @@
1
+ // The agents feature's work: the list, starting an agent in a project of the running sandbox (the sharing rules as the
2
+ // web UI always applied them), and the agents in your settings (added, made default, removed). Talks only through io.
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { DEFAULTS } from '../../../core/config/index.js';
6
+ import { fail, safeText } from '../../../core/util/index.js';
7
+ import { SandboxChannel } from '../../../host/channel/index.js';
8
+ import { insideSandbox, isSandboxRunning } from '../../../host/sandbox/index.js';
9
+ import { ownerRule } from '../../../host/sharing/index.js';
10
+ import { hereDir } from '../../../cli/commands/projects/here.js';
11
+ import { lookAtSandbox } from '../../../cli/commands/shared-use.js';
12
+ import { runningProjects } from '../../../cli/services/web-service.js';
13
+ import { implement } from '../../context.js';
14
+ import { cancelled } from '../../kernel/index.js';
15
+ import { ConfigFile } from '../settings/settings-file.js';
16
+ import { addAgent, listAgents, makeDefaultAgent, removeAgent, startAgent, } from './agents.def.js';
17
+ import { addedAgents, agentNameProblem, checkedAgent, commandFromPackage, newAgent, withAgent, withoutAgent, } from './agent-entry.js';
18
+ /** The longest a start waits for the agent to run (the first start installs it). */
19
+ const SESSION_START_MS = 15 * 60 * 1000;
20
+ /** Writes one setting; a value the config file would refuse is said with what is wrong. */
21
+ function save(file, key, value) {
22
+ const result = file.set(key, value);
23
+ if (typeof result === 'object')
24
+ fail('It could not be saved: ' + result.problems.join('; '));
25
+ }
26
+ /** Is this agent already in the sandbox's persistent storage (so starting it needs no install)? */
27
+ function installed(dataPath, name, harness) {
28
+ const dir = path.join(dataPath, 'tools', 'agents', name);
29
+ return [
30
+ harness.hostExecutable,
31
+ harness.npmBin && harness.npmBin + '.cmd',
32
+ harness.uvBin && harness.uvBin + '.exe',
33
+ ].some((f) => f && fs.existsSync(path.join(dir, f)));
34
+ }
35
+ export const listAgentsRun = implement(listAgents, async (ctx) => {
36
+ const file = ConfigFile.user(ctx.loaded.configPath);
37
+ const config = file.userConfig();
38
+ const removable = addedAgents(Object.keys(config.harnesses));
39
+ const agents = Object.entries(config.harnesses).map(([name, harness]) => ({
40
+ name,
41
+ ready: installed(ctx.dataPath, name, harness),
42
+ isDefault: name === config.defaultHarness,
43
+ removable: removable.includes(name),
44
+ }));
45
+ return { folder: hereDir(ctx), defaultAgent: config.defaultHarness, agents };
46
+ });
47
+ export const startAgentRun = implement(startAgent, async (ctx, input, io) => {
48
+ if (insideSandbox() || !isSandboxRunning())
49
+ fail('No Windows Sandbox is running.', 'Start one with sandbox claude, then try again.');
50
+ const view = lookAtSandbox(ctx);
51
+ if (view.owner && view.owner.kind !== 'none' && view.owner.kind !== 'mine') {
52
+ const rule = ownerRule(view.owner, { kind: 'use' });
53
+ if (rule.kind === 'refuse')
54
+ fail(rule.reason, rule.fix);
55
+ }
56
+ const projects = runningProjects(view);
57
+ const chosen = input.project ??
58
+ (projects.length === 1
59
+ ? projects[0].name
60
+ : await io.choose({
61
+ title: 'Which project?',
62
+ choices: projects.map((p) => ({ value: p.name, label: p.name, description: p.guest })),
63
+ }));
64
+ if (chosen === undefined)
65
+ cancelled();
66
+ const project = projects.find((p) => p.name === chosen);
67
+ if (!project)
68
+ fail('The running sandbox has no project "' + chosen + '".');
69
+ const harness = view.ctx.loaded.config.harnesses[input.agent];
70
+ if (!harness)
71
+ fail('There is no agent called "' + input.agent + '".');
72
+ io.progress('Starting ' + input.agent + ' (the first time sets things up and can take a while)');
73
+ const channel = new SandboxChannel(view.ctx.dataPath);
74
+ const id = channel.requestSession(input.agent, [], project.guest, { harnessSpec: harness });
75
+ const session = await channel.waitForSession(id, SESSION_START_MS, () => undefined);
76
+ return {
77
+ session: safeText(session.id),
78
+ message: 'Started ' + input.agent + ' in ' + project.name + '.',
79
+ };
80
+ });
81
+ export const addAgentRun = implement(addAgent, async (ctx, _input, io) => {
82
+ const file = ConfigFile.user(ctx.loaded.configPath);
83
+ const taken = Object.keys(file.userConfig().harnesses);
84
+ const source = await io.choose({
85
+ title: 'How does the agent get into the sandbox?',
86
+ choices: [
87
+ {
88
+ value: 'npm',
89
+ label: 'An npm package',
90
+ description: 'Installed inside the sandbox with npm once and kept (e.g. @openai/codex).',
91
+ },
92
+ {
93
+ value: 'uv',
94
+ label: 'A Python package',
95
+ description: 'Installed inside the sandbox with uv once and kept (e.g. aider-chat).',
96
+ },
97
+ {
98
+ value: 'host',
99
+ label: 'A program on this PC',
100
+ description: 'An .exe copied from this PC into the sandbox (looked up on PATH and in ~/.local/bin).',
101
+ },
102
+ ],
103
+ });
104
+ if (source === undefined)
105
+ cancelled();
106
+ const kind = source;
107
+ const name = await io.text({
108
+ title: 'Name of the agent',
109
+ lines: ['What you type after "sandbox", e.g. sandbox <name>. Letters, numbers, - and _.'],
110
+ validate: (v) => agentNameProblem(v, taken),
111
+ });
112
+ if (name === undefined)
113
+ cancelled();
114
+ const agent = name.trim();
115
+ if (kind === 'host') {
116
+ const exe = await io.path({
117
+ title: 'Choose the program (.exe)',
118
+ lines: ['The agent program on this PC. It is copied into the sandbox. A bare file name is looked up on PATH.'],
119
+ pathKind: 'file',
120
+ validate: (v) => (v.trim() ? true : 'Choose a file.'),
121
+ });
122
+ if (exe === undefined)
123
+ cancelled();
124
+ const slash = Math.max(exe.lastIndexOf('\\'), exe.lastIndexOf('/'));
125
+ const dir = slash > 0 ? exe.slice(0, slash) : 'auto';
126
+ return saveAgent(file, agent, newAgent('host', exe.slice(slash + 1), '', dir));
127
+ }
128
+ const what = await io.text({
129
+ title: kind === 'npm' ? 'npm package' : 'Python package',
130
+ lines: [
131
+ kind === 'npm'
132
+ ? 'The package to install, optionally with a version: @scope/name or name@latest.'
133
+ : 'The package for `uv tool install`.',
134
+ ],
135
+ validate: (v) => (v.trim() ? true : 'Type it.'),
136
+ });
137
+ if (what === undefined)
138
+ cancelled();
139
+ const command = await io.text({
140
+ title: 'Command',
141
+ lines: ['The command the package provides; it is what runs inside the sandbox.'],
142
+ initial: commandFromPackage(what.trim()),
143
+ validate: (v) => (/^[A-Za-z0-9._-]+$/.test(v.trim()) ? true : 'Letters, numbers, . - and _ only.'),
144
+ });
145
+ if (command === undefined)
146
+ cancelled();
147
+ return saveAgent(file, agent, newAgent(kind, what.trim(), command.trim()));
148
+ });
149
+ /** Checks the entry and writes it into your settings. */
150
+ function saveAgent(file, name, harness) {
151
+ const checked = checkedAgent(harness);
152
+ if (typeof checked === 'string')
153
+ fail('That agent is not valid: ' + checked);
154
+ save(file, ['harnesses'], withAgent(file.valueInFile(['harnesses']), name, harness));
155
+ return { name, message: 'Added ' + name + '.' };
156
+ }
157
+ /** The agent must be one of your settings' agents (built in or added). */
158
+ function knownAgent(file, name) {
159
+ if (!(name in file.userConfig().harnesses))
160
+ fail('There is no agent called "' + name + '".');
161
+ }
162
+ export const makeDefaultAgentRun = implement(makeDefaultAgent, async (ctx, input) => {
163
+ const file = ConfigFile.user(ctx.loaded.configPath);
164
+ knownAgent(file, input.name);
165
+ save(file, ['defaultHarness'], input.name);
166
+ return { message: input.name + ' is the default agent.' };
167
+ });
168
+ export const removeAgentRun = implement(removeAgent, async (ctx, input, io) => {
169
+ const name = input.name;
170
+ if (name in DEFAULTS.harnesses)
171
+ fail(name + ' is built in, so it cannot be removed.');
172
+ const file = ConfigFile.user(ctx.loaded.configPath);
173
+ knownAgent(file, name);
174
+ if (file.userConfig().defaultHarness === name)
175
+ fail(name + ' is the default agent.', 'Make another agent the default first.');
176
+ const yes = await io.confirm({
177
+ title: 'Remove ' + name + '?',
178
+ lines: ['It is taken out of your settings. Its files in the sandbox stay until you clean them up.'],
179
+ yes: 'Remove',
180
+ danger: true,
181
+ implied: true,
182
+ });
183
+ if (!yes)
184
+ cancelled();
185
+ const rest = withoutAgent(file.valueInFile(['harnesses']), name);
186
+ // Nothing of your own left: the setting goes (the built-in agents need no line).
187
+ save(file, ['harnesses'], Object.keys(rest).length ? rest : undefined);
188
+ return { message: 'Removed ' + name + '.' };
189
+ });
@@ -0,0 +1,3 @@
1
+ export * from './agents.def.js';
2
+ export * from './agents.run.js';
3
+ export * from './agent-entry.js';
@@ -0,0 +1,4 @@
1
+ // The agents feature: the list, starting an agent in a project of the running sandbox, and the agents in your settings.
2
+ export * from './agents.def.js';
3
+ export * from './agents.run.js';
4
+ export * from './agent-entry.js';