windows-development-sandbox 1.7.0 → 1.10.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 (432) hide show
  1. package/config.example.json +12 -1
  2. package/dist/app/context.d.ts +8 -0
  3. package/dist/app/context.js +12 -0
  4. package/dist/app/features/defs.d.ts +322 -0
  5. package/dist/app/features/defs.js +28 -0
  6. package/dist/app/features/sandbox/index.d.ts +2 -0
  7. package/dist/app/features/sandbox/index.js +3 -0
  8. package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
  9. package/dist/app/features/sandbox/sandbox.def.js +245 -0
  10. package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
  11. package/dist/app/features/sandbox/sandbox.run.js +98 -0
  12. package/dist/app/features/sessions/index.d.ts +2 -0
  13. package/dist/app/features/sessions/index.js +3 -0
  14. package/dist/app/features/sessions/sessions.def.d.ts +141 -0
  15. package/dist/app/features/sessions/sessions.def.js +176 -0
  16. package/dist/app/features/sessions/sessions.run.d.ts +39 -0
  17. package/dist/app/features/sessions/sessions.run.js +58 -0
  18. package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +2 -0
  19. package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +24 -5
  20. package/dist/app/features/settings/index.d.ts +5 -0
  21. package/dist/app/features/settings/index.js +6 -0
  22. package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
  23. package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
  24. package/dist/app/features/settings/settings-rows.d.ts +35 -0
  25. package/dist/app/features/settings/settings-rows.js +94 -0
  26. package/dist/app/features/settings/settings.def.d.ts +157 -0
  27. package/dist/app/features/settings/settings.def.js +179 -0
  28. package/dist/app/features/settings/settings.run.d.ts +67 -0
  29. package/dist/app/features/settings/settings.run.js +84 -0
  30. package/dist/app/kernel/define.d.ts +143 -0
  31. package/dist/app/kernel/define.js +42 -0
  32. package/dist/app/kernel/errors.d.ts +34 -0
  33. package/dist/app/kernel/errors.js +45 -0
  34. package/dist/app/kernel/fields.d.ts +70 -0
  35. package/dist/app/kernel/fields.js +243 -0
  36. package/dist/app/kernel/index.d.ts +8 -0
  37. package/dist/app/kernel/index.js +10 -0
  38. package/dist/app/kernel/io.d.ts +193 -0
  39. package/dist/app/kernel/io.js +126 -0
  40. package/dist/app/kernel/rpc.d.ts +156 -0
  41. package/dist/app/kernel/rpc.js +47 -0
  42. package/dist/app/kernel/text.d.ts +6 -0
  43. package/dist/app/kernel/text.js +57 -0
  44. package/dist/app/kernel/view.d.ts +146 -0
  45. package/dist/app/kernel/view.js +28 -0
  46. package/dist/app/registry.d.ts +10 -0
  47. package/dist/app/registry.js +50 -0
  48. package/dist/cli/args.d.ts +5 -0
  49. package/dist/cli/args.js +6 -0
  50. package/dist/cli/commands/engine.d.ts +2 -0
  51. package/dist/cli/commands/engine.js +60 -0
  52. package/dist/cli/commands/index.d.ts +1 -1
  53. package/dist/cli/commands/index.js +1 -1
  54. package/dist/cli/commands/launch/launch.js +49 -7
  55. package/dist/cli/commands/launch/prepare.js +3 -3
  56. package/dist/cli/commands/launch/running.js +2 -1
  57. package/dist/cli/commands/launch/summary.d.ts +2 -0
  58. package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
  59. package/dist/cli/commands/maintenance/config-share.js +80 -0
  60. package/dist/cli/commands/maintenance/config.js +8 -82
  61. package/dist/cli/commands/maintenance/logs.js +14 -0
  62. package/dist/cli/commands/registry.js +3 -7
  63. package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
  64. package/dist/cli/commands/repair/checks/contained.js +139 -0
  65. package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
  66. package/dist/cli/commands/repair/checks/hcs.js +28 -0
  67. package/dist/cli/commands/repair/checks/index.js +4 -0
  68. package/dist/cli/commands/repair/checks/pc.js +32 -1
  69. package/dist/cli/commands/repair/checks/sandbox.js +16 -1
  70. package/dist/cli/commands/repair/checks/vpn.js +34 -9
  71. package/dist/cli/commands/repair/env.js +2 -1
  72. package/dist/cli/commands/sessions/index.d.ts +0 -4
  73. package/dist/cli/commands/sessions/index.js +3 -7
  74. package/dist/cli/commands/shared-use.d.ts +5 -2
  75. package/dist/cli/commands/shared-use.js +11 -8
  76. package/dist/cli/commands/storage/contained.d.ts +3 -0
  77. package/dist/cli/commands/storage/contained.js +179 -0
  78. package/dist/cli/commands/storage/offer.js +7 -1
  79. package/dist/cli/commands/storage/storage.js +10 -2
  80. package/dist/cli/commands/user-config.js +1 -1
  81. package/dist/cli/commands/vpn.js +20 -3
  82. package/dist/cli/commands/web.d.ts +5 -0
  83. package/dist/cli/commands/web.js +40 -0
  84. package/dist/cli/index.js +2 -1
  85. package/dist/cli/manifest.d.ts +72 -104
  86. package/dist/cli/manifest.js +64 -39
  87. package/dist/cli/menu/add-agent.d.ts +1 -1
  88. package/dist/cli/menu/add-agent.js +1 -1
  89. package/dist/cli/menu/apps.d.ts +7 -1
  90. package/dist/cli/menu/apps.js +36 -0
  91. package/dist/cli/menu/command-fields.d.ts +1 -1
  92. package/dist/cli/menu/command-form.js +2 -2
  93. package/dist/cli/menu/io-menu.d.ts +29 -0
  94. package/dist/cli/menu/io-menu.js +126 -0
  95. package/dist/cli/menu/live.d.ts +27 -0
  96. package/dist/cli/menu/live.js +69 -0
  97. package/dist/cli/menu/memory.d.ts +19 -0
  98. package/dist/cli/menu/memory.js +53 -0
  99. package/dist/cli/menu/menu.d.ts +10 -1
  100. package/dist/cli/menu/menu.js +27 -9
  101. package/dist/cli/menu/pages/agents-page.d.ts +3 -1
  102. package/dist/cli/menu/pages/agents-page.js +12 -5
  103. package/dist/cli/menu/pages/apps-page.d.ts +3 -1
  104. package/dist/cli/menu/pages/apps-page.js +19 -2
  105. package/dist/cli/menu/pages/list-page.d.ts +27 -0
  106. package/dist/cli/menu/pages/list-page.js +109 -7
  107. package/dist/cli/menu/pages/maintenance-page.d.ts +0 -5
  108. package/dist/cli/menu/pages/maintenance-page.js +17 -19
  109. package/dist/cli/menu/pages/sandbox-page.d.ts +4 -6
  110. package/dist/cli/menu/pages/sandbox-page.js +26 -118
  111. package/dist/cli/menu/pages/scopes.d.ts +1 -1
  112. package/dist/cli/menu/pages/sessions-page.d.ts +5 -11
  113. package/dist/cli/menu/pages/sessions-page.js +19 -88
  114. package/dist/cli/menu/pages/settings-page.d.ts +2 -10
  115. package/dist/cli/menu/pages/settings-page.js +64 -94
  116. package/dist/cli/menu/render-view.d.ts +28 -0
  117. package/dist/cli/menu/render-view.js +112 -0
  118. package/dist/cli/menu/settings/{path-kind.d.ts → ask-path.d.ts} +1 -7
  119. package/dist/cli/menu/settings/ask-path.js +14 -0
  120. package/dist/cli/menu/settings/collections/collection-editor.d.ts +1 -1
  121. package/dist/cli/menu/settings/collections/string-list-editor.d.ts +1 -2
  122. package/dist/cli/menu/settings/collections/string-list-editor.js +1 -1
  123. package/dist/cli/menu/settings/draft.d.ts +1 -1
  124. package/dist/cli/menu/settings/format.d.ts +1 -3
  125. package/dist/cli/menu/settings/format.js +6 -36
  126. package/dist/cli/menu/settings/index.d.ts +1 -3
  127. package/dist/cli/menu/settings/index.js +3 -3
  128. package/dist/cli/menu/settings/object-editor.d.ts +1 -1
  129. package/dist/cli/menu/settings/share.d.ts +36 -0
  130. package/dist/cli/menu/settings/share.js +131 -0
  131. package/dist/cli/menu/settings/value-editor.d.ts +5 -1
  132. package/dist/cli/menu/settings/value-editor.js +57 -54
  133. package/dist/cli/menu/several.js +1 -1
  134. package/dist/cli/menu/share-settings.d.ts +21 -0
  135. package/dist/cli/menu/share-settings.js +112 -0
  136. package/dist/cli/menu/shell.d.ts +21 -5
  137. package/dist/cli/menu/shell.js +31 -6
  138. package/dist/cli/menu/views.d.ts +7 -0
  139. package/dist/cli/menu/views.js +11 -0
  140. package/dist/cli/menu/vpn-login.js +8 -0
  141. package/dist/cli/operations/handler.d.ts +6 -0
  142. package/dist/cli/operations/handler.js +61 -0
  143. package/dist/cli/operations/index.d.ts +4 -0
  144. package/dist/cli/operations/index.js +5 -0
  145. package/dist/cli/operations/input.d.ts +6 -0
  146. package/dist/cli/operations/input.js +37 -0
  147. package/dist/cli/operations/io-cli.d.ts +7 -0
  148. package/dist/cli/operations/io-cli.js +62 -0
  149. package/dist/cli/operations/spec.d.ts +18 -0
  150. package/dist/cli/operations/spec.js +108 -0
  151. package/dist/cli/output/colors.d.ts +2 -2
  152. package/dist/cli/output/colors.js +2 -11
  153. package/dist/cli/output/index.d.ts +1 -0
  154. package/dist/cli/output/index.js +1 -0
  155. package/dist/cli/output/print.d.ts +3 -1
  156. package/dist/cli/output/print.js +7 -3
  157. package/dist/cli/output/progress.d.ts +15 -0
  158. package/dist/cli/output/progress.js +44 -0
  159. package/dist/cli/output/render-view.d.ts +4 -0
  160. package/dist/cli/output/render-view.js +63 -0
  161. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  162. package/dist/cli/services/agent-commands-service.js +11 -2
  163. package/dist/cli/services/logs-service.js +4 -3
  164. package/dist/cli/tui/app.d.ts +6 -1
  165. package/dist/cli/tui/app.js +26 -4
  166. package/dist/cli/tui/list/list-screen.d.ts +14 -0
  167. package/dist/cli/tui/list/list-screen.js +64 -36
  168. package/dist/cli/tui/list/list-types.d.ts +2 -0
  169. package/dist/cli/tui/terminal.d.ts +7 -0
  170. package/dist/cli/tui/terminal.js +30 -10
  171. package/dist/core/config/defaults.js +9 -1
  172. package/dist/core/schema/config.d.ts +14 -0
  173. package/dist/core/schema/config.js +16 -1
  174. package/dist/core/schema/harness.d.ts +1 -0
  175. package/dist/core/schema/harness.js +5 -0
  176. package/dist/core/schema/sandbox.d.ts +6 -0
  177. package/dist/core/schema/sandbox.js +20 -3
  178. package/dist/core/schema/vpn.d.ts +2 -1
  179. package/dist/core/schema/vpn.js +4 -4
  180. package/dist/core/schema/web.d.ts +1 -0
  181. package/dist/core/schema/web.js +4 -1
  182. package/dist/core/types.d.ts +23 -5
  183. package/dist/core/util/fs.d.ts +2 -0
  184. package/dist/core/util/fs.js +9 -0
  185. package/dist/core/util/index.d.ts +1 -1
  186. package/dist/core/util/index.js +1 -1
  187. package/dist/guest/agents/agent-files.d.ts +5 -0
  188. package/dist/guest/agents/agent-files.js +4 -0
  189. package/dist/guest/agents/local-state.d.ts +2 -0
  190. package/dist/guest/agents/local-state.js +21 -1
  191. package/dist/guest/boot/boot.js +5 -2
  192. package/dist/guest/daemon/daemon.js +4 -0
  193. package/dist/guest/daemon/sessions.d.ts +5 -0
  194. package/dist/guest/daemon/sessions.js +17 -3
  195. package/dist/guest/entries/daemon.js +3 -0
  196. package/dist/guest/governor/decide.d.ts +71 -0
  197. package/dist/guest/governor/decide.js +211 -0
  198. package/dist/guest/governor/governor.d.ts +45 -0
  199. package/dist/guest/governor/governor.js +230 -0
  200. package/dist/guest/governor/index.d.ts +2 -0
  201. package/dist/guest/governor/index.js +2 -0
  202. package/dist/guest/network/firewall.d.ts +1 -0
  203. package/dist/guest/network/firewall.js +65 -23
  204. package/dist/guest/runtime/csc.d.ts +1 -0
  205. package/dist/guest/runtime/csc.js +1 -0
  206. package/dist/guest/runtime/process.js +53 -5
  207. package/dist/guest/sessions/viewer.js +3 -1
  208. package/dist/guest/setup/claude-mem.js +12 -4
  209. package/dist/guest/toolchains/languages/node.js +29 -3
  210. package/dist/guest/toolchains/native/rust-extras.js +4 -2
  211. package/dist/guest/vpn/vpn.js +69 -21
  212. package/dist/guest/vpn/wireguard.d.ts +32 -0
  213. package/dist/guest/vpn/wireguard.js +132 -0
  214. package/dist/host/agent-commands/commands.d.ts +4 -0
  215. package/dist/host/agent-commands/commands.js +31 -7
  216. package/dist/host/audit/log.d.ts +1 -1
  217. package/dist/host/channel/attach.d.ts +3 -1
  218. package/dist/host/channel/attach.js +5 -2
  219. package/dist/host/channel/channel.d.ts +2 -0
  220. package/dist/host/channel/channel.js +4 -0
  221. package/dist/host/engines/engine.d.ts +12 -0
  222. package/dist/host/engines/engine.js +1 -0
  223. package/dist/host/engines/hcs/check.d.ts +25 -0
  224. package/dist/host/engines/hcs/check.js +95 -0
  225. package/dist/host/engines/hcs/documents.d.ts +44 -0
  226. package/dist/host/engines/hcs/documents.js +155 -0
  227. package/dist/host/engines/hcs/engine.d.ts +39 -0
  228. package/dist/host/engines/hcs/engine.js +171 -0
  229. package/dist/host/engines/hcs/helper.d.ts +43 -0
  230. package/dist/host/engines/hcs/helper.js +173 -0
  231. package/dist/host/engines/hcs/images.d.ts +37 -0
  232. package/dist/host/engines/hcs/images.js +152 -0
  233. package/dist/host/engines/index.d.ts +7 -0
  234. package/dist/host/engines/index.js +5 -0
  235. package/dist/host/engines/registry.d.ts +16 -0
  236. package/dist/host/engines/registry.js +30 -0
  237. package/dist/host/engines/types.d.ts +58 -0
  238. package/dist/host/engines/types.js +1 -0
  239. package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
  240. package/dist/host/engines/windows-sandbox/engine.js +63 -0
  241. package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
  242. package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
  243. package/dist/host/launch/generate.d.ts +5 -1
  244. package/dist/host/launch/generate.js +50 -8
  245. package/dist/host/launch/index.d.ts +3 -1
  246. package/dist/host/launch/index.js +3 -1
  247. package/dist/host/launch/launch-plan.d.ts +13 -0
  248. package/dist/host/launch/launch-plan.js +26 -0
  249. package/dist/host/launch/mappings.js +2 -1
  250. package/dist/host/launch/risk-notes.d.ts +10 -0
  251. package/dist/host/launch/risk-notes.js +18 -0
  252. package/dist/host/launch/session-file.d.ts +2 -0
  253. package/dist/host/launch/session-file.js +7 -1
  254. package/dist/host/launch/wsb-file.d.ts +28 -4
  255. package/dist/host/launch/wsb-file.js +61 -42
  256. package/dist/host/life/crash-report.d.ts +27 -1
  257. package/dist/host/life/crash-report.js +173 -7
  258. package/dist/host/life/host-memory.d.ts +41 -0
  259. package/dist/host/life/host-memory.js +140 -0
  260. package/dist/host/life/index.d.ts +2 -0
  261. package/dist/host/life/index.js +2 -0
  262. package/dist/host/life/stop-events.d.ts +2 -0
  263. package/dist/host/life/stop-events.js +20 -3
  264. package/dist/host/life/stop-warning.js +1 -1
  265. package/dist/host/life/watchdog.d.ts +56 -0
  266. package/dist/host/life/watchdog.js +124 -0
  267. package/dist/host/native.d.ts +3 -2
  268. package/dist/host/native.js +22 -3
  269. package/dist/host/profile/claude-login.js +3 -2
  270. package/dist/host/sandbox/contained-deps.d.ts +2 -0
  271. package/dist/host/sandbox/contained-deps.js +17 -0
  272. package/dist/host/sandbox/index.d.ts +2 -0
  273. package/dist/host/sandbox/index.js +2 -0
  274. package/dist/host/sandbox/platform.d.ts +2 -0
  275. package/dist/host/sandbox/platform.js +7 -7
  276. package/dist/host/sandbox/tasklist.d.ts +13 -0
  277. package/dist/host/sandbox/tasklist.js +47 -0
  278. package/dist/host/secrets/launch-secrets.js +2 -1
  279. package/dist/host/sharing/current.js +2 -6
  280. package/dist/host/storage/contained/check.d.ts +9 -0
  281. package/dist/host/storage/contained/check.js +37 -0
  282. package/dist/host/storage/contained/contained-storage.d.ts +66 -0
  283. package/dist/host/storage/contained/contained-storage.js +168 -0
  284. package/dist/host/storage/contained/disk-port.d.ts +43 -0
  285. package/dist/host/storage/contained/disk-port.js +122 -0
  286. package/dist/host/storage/contained/index.d.ts +9 -0
  287. package/dist/host/storage/contained/index.js +8 -0
  288. package/dist/host/storage/contained/layout.d.ts +28 -0
  289. package/dist/host/storage/contained/layout.js +45 -0
  290. package/dist/host/storage/contained/resolve.d.ts +4 -0
  291. package/dist/host/storage/contained/resolve.js +30 -0
  292. package/dist/host/storage/contained/setting.d.ts +1 -0
  293. package/dist/host/storage/contained/setting.js +5 -0
  294. package/dist/host/storage/contained/state.d.ts +89 -0
  295. package/dist/host/storage/contained/state.js +166 -0
  296. package/dist/host/storage/contained/transfer.d.ts +24 -0
  297. package/dist/host/storage/contained/transfer.js +121 -0
  298. package/dist/host/storage/index.d.ts +2 -0
  299. package/dist/host/storage/index.js +2 -0
  300. package/dist/host/storage/providers/contained.d.ts +15 -0
  301. package/dist/host/storage/providers/contained.js +39 -0
  302. package/dist/host/storage/providers/folder.d.ts +12 -0
  303. package/dist/host/storage/providers/folder.js +20 -0
  304. package/dist/host/storage/providers/index.d.ts +4 -0
  305. package/dist/host/storage/providers/index.js +3 -0
  306. package/dist/host/storage/providers/registry.d.ts +9 -0
  307. package/dist/host/storage/providers/registry.js +14 -0
  308. package/dist/host/storage/providers/types.d.ts +33 -0
  309. package/dist/host/storage/providers/types.js +1 -0
  310. package/dist/host/tools/conpty.js +3 -2
  311. package/dist/host/tools/windows-terminal.js +8 -7
  312. package/dist/host/vpn/index.d.ts +1 -1
  313. package/dist/host/vpn/index.js +1 -1
  314. package/dist/host/vpn/prepare.d.ts +2 -0
  315. package/dist/host/vpn/prepare.js +63 -2
  316. package/dist/host/web/browser.d.ts +2 -0
  317. package/dist/host/web/browser.js +14 -1
  318. package/dist/host/web/index.d.ts +3 -2
  319. package/dist/host/web/index.js +3 -2
  320. package/dist/host/web/rpc.d.ts +24 -0
  321. package/dist/host/web/rpc.js +149 -0
  322. package/dist/host/web/runner.d.ts +2 -0
  323. package/dist/host/web/runner.js +1 -2
  324. package/dist/host/web/server.d.ts +7 -0
  325. package/dist/host/web/server.js +23 -3
  326. package/dist/runtime/agent.js +83 -18
  327. package/dist/runtime/daemon.js +1805 -1221
  328. package/dist/runtime/db.js +83 -18
  329. package/dist/runtime/main.js +779 -219
  330. package/dist/runtime/netproxy.js +73 -11
  331. package/dist/runtime/view.js +91 -16
  332. package/dist/selftest/agent-paths.test.js +11 -1
  333. package/dist/selftest/app.test.d.ts +2 -0
  334. package/dist/selftest/app.test.js +324 -0
  335. package/dist/selftest/channel.test.js +13 -0
  336. package/dist/selftest/cli.test.js +2 -1
  337. package/dist/selftest/config.test.js +59 -0
  338. package/dist/selftest/contained.test.d.ts +2 -0
  339. package/dist/selftest/contained.test.js +544 -0
  340. package/dist/selftest/credentials.test.js +1 -1
  341. package/dist/selftest/engine.test.d.ts +2 -0
  342. package/dist/selftest/engine.test.js +127 -0
  343. package/dist/selftest/guest-boot.test.js +47 -1
  344. package/dist/selftest/hcs.test.d.ts +2 -0
  345. package/dist/selftest/hcs.test.js +482 -0
  346. package/dist/selftest/heavy-load.test.d.ts +2 -0
  347. package/dist/selftest/heavy-load.test.js +355 -0
  348. package/dist/selftest/index.js +12 -0
  349. package/dist/selftest/layout.test.js +12 -0
  350. package/dist/selftest/menu-perf.test.d.ts +2 -0
  351. package/dist/selftest/menu-perf.test.js +248 -0
  352. package/dist/selftest/menu-screens.js +4 -2
  353. package/dist/selftest/menu.test.js +36 -8
  354. package/dist/selftest/network.test.js +20 -1
  355. package/dist/selftest/support/engine-cases.d.ts +8 -0
  356. package/dist/selftest/support/engine-cases.js +65 -0
  357. package/dist/selftest/support/engine-golden.d.ts +3 -0
  358. package/dist/selftest/support/engine-golden.js +66 -0
  359. package/dist/selftest/support/fixtures.d.ts +8 -1
  360. package/dist/selftest/support/hcs-probes.d.ts +17 -0
  361. package/dist/selftest/support/hcs-probes.js +41 -0
  362. package/dist/selftest/vpn.test.js +136 -3
  363. package/dist/selftest/web.test.js +101 -3
  364. package/dist/shared/channel/run-dir.d.ts +4 -1
  365. package/dist/shared/channel/run-dir.js +7 -1
  366. package/dist/shared/channel/schema.d.ts +35 -1
  367. package/dist/shared/channel/schema.js +27 -0
  368. package/dist/shared/channel/secrets.d.ts +1 -0
  369. package/dist/shared/channel/secrets.js +6 -0
  370. package/dist/shared/io/copy-tree.d.ts +7 -0
  371. package/dist/shared/io/copy-tree.js +45 -0
  372. package/dist/shared/io/index.d.ts +2 -0
  373. package/dist/shared/io/index.js +2 -0
  374. package/dist/shared/io/robocopy-result.d.ts +6 -0
  375. package/dist/shared/io/robocopy-result.js +23 -0
  376. package/dist/shared/memory/index.d.ts +1 -0
  377. package/dist/shared/memory/index.js +1 -0
  378. package/dist/shared/memory/policy.d.ts +38 -0
  379. package/dist/shared/memory/policy.js +63 -0
  380. package/dist/shared/network/firewall-rules.d.ts +8 -0
  381. package/dist/shared/network/firewall-rules.js +28 -0
  382. package/dist/shared/pty/output-filter.d.ts +14 -1
  383. package/dist/shared/pty/output-filter.js +22 -4
  384. package/dist/shared/pty/terminal.d.ts +4 -1
  385. package/dist/shared/pty/terminal.js +4 -2
  386. package/dist/shared/system.d.ts +1 -0
  387. package/dist/shared/system.js +1 -0
  388. package/dist/shared/vpn/download.d.ts +16 -0
  389. package/dist/shared/vpn/download.js +16 -0
  390. package/dist/shared/vpn/wireguard.d.ts +51 -0
  391. package/dist/shared/vpn/wireguard.js +227 -0
  392. package/dist/sync/sync-cycle.js +5 -5
  393. package/dist/sync/watcher.d.ts +13 -0
  394. package/dist/sync/watcher.js +92 -3
  395. package/dist/web/index.html +4 -3
  396. package/dist/web/main-NRRS5O6Z.js +157 -0
  397. package/dist/web/main-T5DMCHYV.css +1 -0
  398. package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
  399. package/native/csharp/HcsHost/Guard.cs +100 -0
  400. package/native/csharp/HcsHost/Hcs.cs +256 -0
  401. package/native/csharp/HcsHost/Json.cs +78 -0
  402. package/native/csharp/HcsHost/Program.cs +185 -0
  403. package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
  404. package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
  405. package/native/csharp/HostTools/MemoryStatus.cs +128 -0
  406. package/native/csharp/HostTools/Program.cs +58 -17
  407. package/native/scripts/check-contained.ps1 +28 -0
  408. package/native/scripts/contained-common.ps1 +241 -0
  409. package/native/scripts/dismount-contained.ps1 +66 -0
  410. package/native/scripts/memory-status.ps1 +42 -0
  411. package/native/scripts/mount-contained.ps1 +139 -0
  412. package/native/scripts/run-elevated.ps1 +17 -4
  413. package/native/scripts/stop-events.ps1 +23 -8
  414. package/package.json +9 -2
  415. package/sandbox/csharp/MemGov.cs +466 -0
  416. package/sandbox/csharp/PtyHost.cs +111 -5
  417. package/sandbox/scripts/new-shortcuts.ps1 +3 -1
  418. package/schemas/config.schema.json +66 -8
  419. package/schemas/sandbox-config.schema.json +3 -3
  420. package/dist/cli/commands/sessions/control.d.ts +0 -4
  421. package/dist/cli/commands/sessions/control.js +0 -66
  422. package/dist/cli/commands/sessions/list.d.ts +0 -2
  423. package/dist/cli/commands/sessions/list.js +0 -48
  424. package/dist/cli/commands/sessions/status.d.ts +0 -4
  425. package/dist/cli/commands/sessions/status.js +0 -114
  426. package/dist/cli/commands/sessions/window.d.ts +0 -3
  427. package/dist/cli/commands/sessions/window.js +0 -18
  428. package/dist/cli/menu/settings/path-kind.js +0 -44
  429. package/dist/web/main-CXESL347.js +0 -45
  430. package/dist/web/main-VLR7DVQ4.css +0 -1
  431. /package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +0 -0
  432. /package/dist/{cli/menu/settings → app/kernel}/schema-node.js +0 -0
@@ -1,13 +1,13 @@
1
1
  // The VPN setting (inside the sandbox only; the login is not a setting: it is kept encrypted by `sandbox vpn login`).
2
2
  import { z } from 'zod';
3
- export const VPN_PROVIDERS = ['nordvpn', 'openvpn-file'];
3
+ export const VPN_PROVIDERS = ['nordvpn', 'openvpn-file', 'wireguard-file'];
4
4
  export const VpnSchema = z.strictObject({
5
5
  enabled: z
6
6
  .boolean()
7
- .describe("Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."),
7
+ .describe("(Alpha: not yet tried on a real PC) Send the sandbox's traffic through a VPN. Only the sandbox: your PC's own connection is untouched. Needs a saved login first (sandbox vpn login). The agent in the sandbox can read that login and can turn the tunnel off (it is the administrator there)."),
8
8
  provider: z
9
9
  .enum(VPN_PROVIDERS)
10
- .describe('nordvpn: a recommended NordVPN server is picked at every launch. openvpn-file: your own .ovpn file (configFile).'),
10
+ .describe('nordvpn: a recommended NordVPN server is picked at every launch. openvpn-file: your own .ovpn file (configFile). wireguard-file: your own WireGuard .conf (configFile), e.g. from your company.'),
11
11
  protocol: z.enum(['udp', 'tcp']).describe('udp is faster; tcp gets through networks that block udp.'),
12
12
  country: z
13
13
  .string()
@@ -15,7 +15,7 @@ export const VpnSchema = z.strictObject({
15
15
  .describe('nordvpn: the country of the server, e.g. uk, us or Germany. Empty = the best server anywhere.'),
16
16
  configFile: z
17
17
  .string()
18
- .describe("openvpn-file: the .ovpn file on this PC (its certificates inside it). Files that run programs (script-security, up, down, plugin ...) are refused. A project's file can never set this."),
18
+ .describe("openvpn-file / wireguard-file: the .ovpn or .conf file on this PC (an .ovpn has its certificates inside it). Files that run programs (script-security, up, down, plugin, PostUp ...) are refused. A WireGuard file holds your private key: it is read when a sandbox starts and handed over in a one-shot file. A project's file can never set this."),
19
19
  killSwitch: z
20
20
  .boolean()
21
21
  .describe('Block all traffic that does not go through the tunnel: when the tunnel cannot start, the sandbox stays offline instead of using your normal connection. A project can only turn this on, never off.'),
@@ -3,4 +3,5 @@ export declare const WEB_DEFAULT_PORT = 47800;
3
3
  export declare const WebSchema: z.ZodObject<{
4
4
  enabled: z.ZodBoolean;
5
5
  port: z.ZodNumber;
6
+ openOnLaunch: z.ZodBoolean;
6
7
  }, z.core.$strict>;
@@ -4,11 +4,14 @@ export const WEB_DEFAULT_PORT = 47800;
4
4
  export const WebSchema = z.strictObject({
5
5
  enabled: z
6
6
  .boolean()
7
- .describe('(Beta) Allow the web UI: your sandbox sessions in a browser on this PC. Off by default, and nothing starts it by itself yet: sandbox web start works either way and runs it until sandbox web stop (or a restart of the PC).'),
7
+ .describe('(Beta) The web UI: your sandbox sessions in a browser on this PC (http://127.0.0.1:<port>, this PC only). On: every sandbox start also starts it in the background (it keeps running until sandbox web stop or a restart of the PC). Off: only sandbox web start runs it. Open it signed in with sandbox web open.'),
8
8
  port: z
9
9
  .number()
10
10
  .int()
11
11
  .min(1024)
12
12
  .max(65535)
13
13
  .describe('Port of the web UI on 127.0.0.1 (this PC only). Pick another when it is taken.'),
14
+ openOnLaunch: z
15
+ .boolean()
16
+ .describe('(Beta) With the web UI on: open it in your browser, already signed in, every time a sandbox starts.'),
14
17
  });
@@ -105,12 +105,15 @@ export interface DatabasePlan {
105
105
  /** The VPN decided at launch (host/vpn/prepare.ts): its checked profile, and the login for the one-shot file. */
106
106
  export interface PreparedVpn {
107
107
  session: GuestVpn;
108
- /** The profile text, already checked. */
109
- profile: string;
110
- credentials: {
108
+ /** openvpn: the profile text, already checked (goes in the launch folder). */
109
+ profile?: string;
110
+ /** openvpn: the login (one-shot file). */
111
+ credentials?: {
111
112
  username: string;
112
113
  password: string;
113
114
  };
115
+ /** wireguard-file: the checked config; holds the private key (one-shot file only). */
116
+ wireguardConfig?: string;
114
117
  }
115
118
  /** databases / pcLanguages: use these instead of scanning (tests). */
116
119
  export interface GenerateOptions {
@@ -119,6 +122,8 @@ export interface GenerateOptions {
119
122
  harnessArgs: string[];
120
123
  probe: HostProbe;
121
124
  freeMemoryBytes?: number;
125
+ /** This PC's unused commit (RAM plus paging file) in MB from HostTools memory-status; omitted = not checked. */
126
+ commitAvailableMb?: number | null;
122
127
  databases?: DatabasePlan[];
123
128
  pcLanguages?: AutoToolchain[];
124
129
  /**
@@ -136,6 +141,8 @@ export interface GenerateOptions {
136
141
  };
137
142
  /** The VPN for this launch (vpn.enabled); its profile goes in the launch folder, its login in the one-shot file. */
138
143
  vpn?: PreparedVpn;
144
+ /** The data set's mappings from a storage provider (contained storage); else the data folder is one mapping. */
145
+ dataMappings?: ResolvedMapping[];
139
146
  }
140
147
  export interface Generated {
141
148
  wsbPath: string;
@@ -143,6 +150,8 @@ export interface Generated {
143
150
  launchId: string;
144
151
  sessionPath: string;
145
152
  memoryMb: number;
153
+ /** Plain words when the PC's commit made the memory much smaller than free RAM allowed. */
154
+ memoryNote: string | null;
146
155
  /** The config the sandbox boots with: the launch folder's plus what the other projects mapped at boot want. */
147
156
  bootConfig: Config;
148
157
  /** Boot settings turned on for another project (setting -> project). */
@@ -181,8 +190,8 @@ export interface GuestVpn {
181
190
  killSwitch: boolean;
182
191
  /** The server's name, for messages. */
183
192
  server: string;
184
- /** The checked profile, relative to the launch folder. */
185
- profile: string;
193
+ /** openvpn: the checked profile, relative to the launch folder (none for wireguard-file: its config is a secret). */
194
+ profile?: string;
186
195
  }
187
196
  /** Written by the host to C:\AgentLaunch\session.json (read-only for the guest): everything the guest needs to know. */
188
197
  export interface GuestSession {
@@ -253,6 +262,15 @@ export interface GuestSession {
253
262
  cpuLimitPercent?: number | null;
254
263
  /** sandbox.pageFileMb (0 = Windows' own); sandbox\scripts\set-page-file.ps1 applies it at logon. */
255
264
  pageFileMb?: number;
265
+ /**
266
+ * sandbox.agentMemoryHeadroomMb as a limit: the most memory (MB) everything the agents start may use together
267
+ * (the sandbox's memory minus the headroom); null = no limit. ptyhost puts each agent in a job object with it.
268
+ */
269
+ agentMemoryLimitMb?: number | null;
270
+ /** "gentle" when vGPU is on: the governor and the watchdog act earlier, compilers run below normal. */
271
+ loadProfile?: 'normal' | 'gentle';
272
+ /** sandbox.pressureResponse: the daemon slows builds down when memory runs low. */
273
+ pressureResponse?: boolean;
256
274
  /** Apps to install (catalogue ids and your own programs); missing in launch folders of older versions. */
257
275
  apps?: Config['apps'];
258
276
  /** audit.enabled and audit.processes: the sandbox reports the programs it starts (host keeps the log). */
@@ -1,6 +1,8 @@
1
1
  export declare function ensureDir(p: string): void;
2
2
  export declare function dirExists(p: string): boolean;
3
3
  export declare function fileExists(p: string): boolean;
4
+ /** fileExists without blocking the program (the menu looks for programs while it stays responsive). */
5
+ export declare function fileExistsAsync(p: string): Promise<boolean>;
4
6
  export declare function readJson<T>(p: string): T;
5
7
  export declare function tryReadJson<T>(p: string): T | null;
6
8
  /** Atomic (a crash or a second command never leaves half a file); refused outside temp during the self-test. */
@@ -19,6 +19,15 @@ export function fileExists(p) {
19
19
  return false;
20
20
  }
21
21
  }
22
+ /** fileExists without blocking the program (the menu looks for programs while it stays responsive). */
23
+ export async function fileExistsAsync(p) {
24
+ try {
25
+ return (await fs.promises.stat(p)).isFile();
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
22
31
  export function readJson(p) {
23
32
  return JSON.parse(fs.readFileSync(p, 'utf8').replace(/^\uFEFF/, ''));
24
33
  }
@@ -1,7 +1,7 @@
1
1
  export { isWin, sleep, captureOutput } from './process.js';
2
2
  export { UserError, fail, errMsg } from './errors.js';
3
3
  export { parseJsonc, readJsonc } from './jsonc.js';
4
- export { ensureDir, dirExists, fileExists, readJson, tryReadJson, writeJson, realPath } from './fs.js';
4
+ export { ensureDir, dirExists, fileExists, fileExistsAsync, readJson, tryReadJson, writeJson, realPath } from './fs.js';
5
5
  export { xmlEscape, safeText, plainText } from './text.js';
6
6
  export { homeDir, expandPath, expandVariables, isRootPath, isUserProfile, isInsideOrEqual, findOnPath, } from './paths.js';
7
7
  export { isLink, removeLink, assertNoLinks } from './links.js';
@@ -1,7 +1,7 @@
1
1
  export { isWin, sleep, captureOutput } from './process.js';
2
2
  export { UserError, fail, errMsg } from './errors.js';
3
3
  export { parseJsonc, readJsonc } from './jsonc.js';
4
- export { ensureDir, dirExists, fileExists, readJson, tryReadJson, writeJson, realPath } from './fs.js';
4
+ export { ensureDir, dirExists, fileExists, fileExistsAsync, readJson, tryReadJson, writeJson, realPath } from './fs.js';
5
5
  export { xmlEscape, safeText, plainText } from './text.js';
6
6
  export { homeDir, expandPath, expandVariables, isRootPath, isUserProfile, isInsideOrEqual, findOnPath, } from './paths.js';
7
7
  export { isLink, removeLink, assertNoLinks } from './links.js';
@@ -43,6 +43,11 @@ export interface LocalState {
43
43
  readonly legacy: string;
44
44
  }
45
45
  export declare function localStateEntries(agents: Readonly<Record<string, Harness>>, stateDir: string, localRoot: string): LocalState[];
46
+ /** Every agent's bootReset paths, absolute below its state folder (the schema allows only plain relative paths). */
47
+ export declare function bootResetPaths(agents: Readonly<Record<string, Harness>>, stateDir: string): {
48
+ agent: string;
49
+ path: string;
50
+ }[];
46
51
  /** A SQLite database file or one of its -wal / -shm siblings. */
47
52
  export declare const isDatabaseFile: (name: string) => boolean;
48
53
  /** Files that make a consistent copy: the databases and their -wal (the -shm is rebuilt by SQLite). */
@@ -57,6 +57,10 @@ export function localStateEntries(agents, stateDir, localRoot) {
57
57
  legacy: path.join(stateDir, agent),
58
58
  })));
59
59
  }
60
+ /** Every agent's bootReset paths, absolute below its state folder (the schema allows only plain relative paths). */
61
+ export function bootResetPaths(agents, stateDir) {
62
+ return Object.entries(agents).flatMap(([agent, harness]) => (harness.bootReset ?? []).map((rel) => ({ agent, path: path.join(stateDir, agent, rel) })));
63
+ }
60
64
  /** A SQLite database file or one of its -wal / -shm siblings. */
61
65
  export const isDatabaseFile = (name) => /\.(sqlite3?|db)(-wal|-shm)?$/i.test(name);
62
66
  /** Files that make a consistent copy: the databases and their -wal (the -shm is rebuilt by SQLite). */
@@ -3,6 +3,8 @@ import { type LocalState } from './agent-files.js';
3
3
  export declare function agentLocalStates(): LocalState[];
4
4
  /** Variable -> working folder, for the agent environment (and the machine environment of new terminal tabs). */
5
5
  export declare function localStateVars(): Record<string, string>;
6
+ /** Boot: what an agent sealed to the last sandbox (bootReset) is deleted, so it sets it up again. Links are left. */
7
+ export declare function resetMachineBound(): void;
6
8
  /** Boot: the saved databases of every configured agent are copied to the sandbox's disk, where the agent runs them. */
7
9
  export declare function restoreLocalState(): void;
8
10
  /**
@@ -10,7 +10,7 @@ import { execOutput } from '../runtime/process.js';
10
10
  import { log, warn } from '../runtime/log.js';
11
11
  import { session, stateDir } from '../runtime/session.js';
12
12
  import { errMsg } from '../../core/util/errors.js';
13
- import { isCopyableDatabaseFile, isDatabaseFile, localStateEntries } from './agent-files.js';
13
+ import { bootResetPaths, isCopyableDatabaseFile, isDatabaseFile, localStateEntries, } from './agent-files.js';
14
14
  const SQLITE_HEADER = 'SQLite format 3\0';
15
15
  /** The sandbox-disk folder that holds the working copies. */
16
16
  const localRoot = () => path.join(localDir, 'agent-state');
@@ -82,6 +82,26 @@ function adoptLegacy(s) {
82
82
  fs.rmSync(path.join(s.legacy, n), { force: true });
83
83
  log(s.agent + ': moved ' + copyable.length + ' database file(s) to ' + s.store + '.');
84
84
  }
85
+ /** Boot: what an agent sealed to the last sandbox (bootReset) is deleted, so it sets it up again. Links are left. */
86
+ export function resetMachineBound() {
87
+ if (dryRun)
88
+ return;
89
+ for (const { agent, path: target } of bootResetPaths(session.agents ?? {}, stateDir)) {
90
+ try {
91
+ const stat = fs.lstatSync(target, { throwIfNoEntry: false });
92
+ if (!stat || stat.isSymbolicLink())
93
+ continue;
94
+ fs.rmSync(target, { recursive: true, force: true });
95
+ log(agent +
96
+ ': removed ' +
97
+ path.relative(path.join(stateDir, agent), target) +
98
+ ' (it only worked in the last sandbox).');
99
+ }
100
+ catch (e) {
101
+ warn(agent + ': could not remove ' + target + ' (' + errMsg(e) + ').');
102
+ }
103
+ }
104
+ }
85
105
  /** Boot: the saved databases of every configured agent are copied to the sandbox's disk, where the agent runs them. */
86
106
  export function restoreLocalState() {
87
107
  if (dryRun)
@@ -6,7 +6,7 @@ import { writeGuides } from './guide.js';
6
6
  import { setupToolchains } from '../toolchains/index.js';
7
7
  import { agents } from '../agents/agent-installer.js';
8
8
  import { agentShims, sbxAgentText, shimText } from '../agents/agent-files.js';
9
- import { restoreLocalState } from '../agents/local-state.js';
9
+ import { resetMachineBound, restoreLocalState } from '../agents/local-state.js';
10
10
  import { installShellPath } from '../setup/shell-path.js';
11
11
  import { linkProfileDirs } from '../agents/profile-links.js';
12
12
  import { restoreClaudeMem } from '../setup/claude-mem.js';
@@ -14,7 +14,7 @@ import { syncClaudeProfile } from '../setup/claude-profile.js';
14
14
  import { agentEnv, persistEnvironment } from '../setup/environment.js';
15
15
  import { runHooks } from '../setup/hooks.js';
16
16
  import { applyAllowOnly, proxyEnv } from '../network/allow-only.js';
17
- import { applyNetworkPolicy } from '../network/firewall.js';
17
+ import { applyNetworkPolicy, networkProblems } from '../network/firewall.js';
18
18
  import { writeManagedSettings } from '../setup/managed-policy.js';
19
19
  import { applyPersonalization } from '../setup/desktop.js';
20
20
  import { setupGitConfig } from '../setup/git-identity.js';
@@ -175,6 +175,8 @@ export class Boot {
175
175
  databases: session.databases ?? [],
176
176
  apps: session.apps,
177
177
  });
178
+ for (const p of networkProblems())
179
+ tools.summary.push('PROTECTION MISSING: ' + p);
178
180
  if (!dryRun)
179
181
  tools.prepend.push(writeDbCommand());
180
182
  // network.allowOnly / network.proxy: everything started from now on uses the proxy.
@@ -225,6 +227,7 @@ export class Boot {
225
227
  if (session.harnessName === 'claude')
226
228
  await soft('Claude settings', () => syncClaudeProfile(this.secrets.claudeCredentials));
227
229
  await soft('claude-mem restore', restoreClaudeMem);
230
+ await soft('Agent files of the last sandbox', resetMachineBound);
228
231
  await soft('Agent databases restore', restoreLocalState);
229
232
  await soft('Sandbox guide for the agent', () => writeGuides(tools.summary, this.lan));
230
233
  await soft('Claude managed settings', () => writeManagedSettings(this.gitAccess));
@@ -4,6 +4,7 @@ import { saveClaudeMem } from '../setup/claude-mem.js';
4
4
  import { saveLocalState } from '../agents/local-state.js';
5
5
  import { execCommand } from './exec.js';
6
6
  import { sessions } from './sessions.js';
7
+ import { governor } from '../governor/index.js';
7
8
  import { respond, safely } from './state.js';
8
9
  import { run } from '../runtime/paths.js';
9
10
  import { withRequestSecrets } from '../runtime/secrets.js';
@@ -53,6 +54,9 @@ export class Daemon {
53
54
  return execCommand(req);
54
55
  case 'restart':
55
56
  return sessions.restart(req);
57
+ case 'pressure':
58
+ // No response: the host repeats it every few seconds while its memory stays low.
59
+ return governor.hostPressure(req.seconds, req.reason);
56
60
  case 'ping':
57
61
  return respond(req.id, { ok: true, message: 'pong (' + sessions.count + ' session(s) running)' });
58
62
  }
@@ -2,6 +2,11 @@ import type { GuestRequest } from '../../core/types.js';
2
2
  type SessionRequest = Extract<GuestRequest, {
3
3
  kind: 'session';
4
4
  }>;
5
+ /**
6
+ * What keeps heavy load from taking the sandbox down: the job object's memory limit for everything the agents start
7
+ * (ptyhost reads PTYHOST_JOB_MB) and cargo's parallel jobs sized to the sandbox's memory and the sessions building.
8
+ */
9
+ export declare function memoryEnv(env: NodeJS.ProcessEnv, sessions: number): NodeJS.ProcessEnv;
5
10
  /** The agent sessions of this sandbox: the running ones, the ones starting, and what happens when one ends. */
6
11
  export declare class SessionManager {
7
12
  private readonly live;
@@ -3,11 +3,13 @@
3
3
  // (daemon/project).
4
4
  import path from 'node:path';
5
5
  import crypto from 'node:crypto';
6
+ import os from 'node:os';
6
7
  import { spawn } from 'node:child_process';
7
8
  import { FrameType, sendControl } from '../../shared/pty/index.js';
8
9
  import { isWithin } from '../../shared/paths/projects.js';
9
10
  import { now } from '../../shared/channel/run-dir.js';
10
11
  import { SYSTEM } from '../../shared/system.js';
12
+ import { cargoJobs } from '../../shared/memory/index.js';
11
13
  import { commandLine } from '../sessions/cmdline.js';
12
14
  import { freePort } from '../runtime/ports.js';
13
15
  import { primaryProject } from '../boot/project-status.js';
@@ -48,8 +50,20 @@ const harnessFor = (req) => {
48
50
  return sent;
49
51
  throw new Error('Agent "' + req.harness + '" is not configured for this sandbox (it runs ' + session.harnessName + ').');
50
52
  };
53
+ /**
54
+ * What keeps heavy load from taking the sandbox down: the job object's memory limit for everything the agents start
55
+ * (ptyhost reads PTYHOST_JOB_MB) and cargo's parallel jobs sized to the sandbox's memory and the sessions building.
56
+ */
57
+ export function memoryEnv(env, sessions) {
58
+ const out = {};
59
+ if (session.agentMemoryLimitMb)
60
+ out.PTYHOST_JOB_MB = String(session.agentMemoryLimitMb);
61
+ if (!env.CARGO_BUILD_JOBS)
62
+ out.CARGO_BUILD_JOBS = String(cargoJobs(os.cpus().length, os.totalmem() / 1024 ** 3, sessions));
63
+ return out;
64
+ }
51
65
  /** Starts ptyhost for the agent and waits until it listens; a failure carries the tail of ptyhost's own log. */
52
- const launchPtyHost = async (req, remote, env, say) => {
66
+ const launchPtyHost = async (req, remote, env, say, sessions) => {
53
67
  const harness = harnessFor(req);
54
68
  // Never refresh here: main already did, and replacing a running agent's executable would fail.
55
69
  say('Preparing ' + req.harness);
@@ -66,7 +80,7 @@ const launchPtyHost = async (req, remote, env, say) => {
66
80
  rows: 32,
67
81
  id: req.id,
68
82
  cwd: req.cwd,
69
- env: { ...withRegistryPath(env), ...harness.environment },
83
+ env: { ...withRegistryPath(env), ...harness.environment, ...memoryEnv(env, sessions) },
70
84
  remote,
71
85
  command: commandLine(launch.file, [...base, ...req.args]),
72
86
  restartCommand: commandLine(launch.file, [...base, ...(harness.resumeArguments ?? [])]),
@@ -145,7 +159,7 @@ export class SessionManager {
145
159
  try {
146
160
  const place = await placeFor(req, say);
147
161
  const remote = session.networking && session.attach.enabled;
148
- const { child, port, token } = await launchPtyHost(req, remote, place.env, say);
162
+ const { child, port, token } = await launchPtyHost(req, remote, place.env, say, this.live.size + 1);
149
163
  const resumed = req.harness === 'claude' ? resumedConversation(req.args) : undefined;
150
164
  const running = {
151
165
  ...status,
@@ -9,10 +9,13 @@ import { log, warn } from '../runtime/log.js';
9
9
  import { adoptBootSecrets } from '../runtime/secrets.js';
10
10
  import { errMsg } from '../../core/util/errors.js';
11
11
  import { Daemon } from '../daemon/daemon.js';
12
+ import { governor } from '../governor/index.js';
12
13
  process.on('uncaughtException', (e) => warn('daemon: unexpected error (continuing): ' + (e.stack ?? errMsg(e))));
13
14
  process.on('unhandledRejection', (e) => warn('daemon: unexpected error (continuing): ' + errMsg(e)));
14
15
  adoptBootSecrets();
15
16
  log('Session daemon started (pid ' + process.pid + ').');
16
17
  safely('port forwards', startRelays);
17
18
  safely('audit', startProcessCollector);
19
+ safely('memory governor', () => governor.start());
20
+ log('Memory governor: ' + governor.describe());
18
21
  new Daemon().start();
@@ -0,0 +1,71 @@
1
+ import type { GuestThresholds, LoadProfile } from '../../shared/memory/index.js';
2
+ export type Priority = 'idle' | 'below' | 'normal';
3
+ export interface ProcSample {
4
+ readonly pid: number;
5
+ readonly name: string;
6
+ /** Private memory in MB. */
7
+ readonly mb: number;
8
+ readonly prio: Priority;
9
+ }
10
+ export interface MemSample {
11
+ readonly ramTotalMb: number;
12
+ readonly ramAvailMb: number;
13
+ readonly commitLimitMb: number;
14
+ readonly commitAvailMb: number;
15
+ /** Only the processes in the agents' job. */
16
+ readonly procs: readonly ProcSample[];
17
+ }
18
+ export declare const isNeverTouched: (name: string) => boolean;
19
+ export declare const canLower: (name: string) => boolean;
20
+ export declare const isHeavyCompiler: (name: string) => boolean;
21
+ export declare const canPause: (name: string) => boolean;
22
+ export type Level = 'ok' | 'throttled' | 'suspending';
23
+ export interface GovernorState {
24
+ /** Under pressure now (with hysteresis). */
25
+ readonly pressure: boolean;
26
+ /** Samples in a row that looked calm while under pressure. */
27
+ readonly calm: number;
28
+ /** Samples under pressure so far (resets when it ends). */
29
+ readonly samples: number;
30
+ /** What was lowered and to what, by pid. */
31
+ readonly lowered: Readonly<Record<number, Priority>>;
32
+ /** Until when (ms) the last pause lasts, and when another may start. */
33
+ readonly pausedUntil: number;
34
+ readonly nextPauseAt: number;
35
+ /** The PC asked for slowing down until this time (ms). */
36
+ readonly hostUntil: number;
37
+ }
38
+ export declare const INITIAL_STATE: GovernorState;
39
+ export type Action = {
40
+ readonly kind: 'priority';
41
+ readonly pid: number;
42
+ readonly name: string;
43
+ readonly to: Priority;
44
+ } | {
45
+ readonly kind: 'pause';
46
+ readonly pid: number;
47
+ readonly name: string;
48
+ readonly ms: number;
49
+ }
50
+ /** Waits (suspended) because more compilers run than the cap allows; repeated while it is over, never killed. */
51
+ | {
52
+ readonly kind: 'hold';
53
+ readonly pid: number;
54
+ readonly name: string;
55
+ readonly ms: number;
56
+ };
57
+ /** How long a held compiler waits before it gets a turn again (the governor repeats the hold while over the cap). */
58
+ export declare const HOLD_MS = 3000;
59
+ export interface Decision {
60
+ readonly state: GovernorState;
61
+ readonly actions: readonly Action[];
62
+ readonly level: Level;
63
+ readonly ramFreePercent: number;
64
+ readonly commitPercent: number;
65
+ }
66
+ export declare const PAUSE_MS = 5000;
67
+ /**
68
+ * One step. `gentle` (vGPU on): compilers start below normal even without pressure. Programs go back to their normal
69
+ * priority only when pressure ends (several calm samples in a row).
70
+ */
71
+ export declare function decide(prev: GovernorState, sample: MemSample, nowMs: number, thresholds: GuestThresholds, profile: LoadProfile, maxCompilers?: number | null): Decision;