windows-development-sandbox 1.5.0 → 1.9.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 (709) hide show
  1. package/README.md +1 -0
  2. package/config.example.json +27 -1
  3. package/dist/app/context.d.ts +8 -0
  4. package/dist/app/context.js +12 -0
  5. package/dist/app/features/defs.d.ts +322 -0
  6. package/dist/app/features/defs.js +28 -0
  7. package/dist/app/features/sandbox/index.d.ts +2 -0
  8. package/dist/app/features/sandbox/index.js +3 -0
  9. package/dist/app/features/sandbox/sandbox.def.d.ts +193 -0
  10. package/dist/app/features/sandbox/sandbox.def.js +245 -0
  11. package/dist/app/features/sandbox/sandbox.run.d.ts +72 -0
  12. package/dist/app/features/sandbox/sandbox.run.js +98 -0
  13. package/dist/app/features/sessions/index.d.ts +2 -0
  14. package/dist/app/features/sessions/index.js +3 -0
  15. package/dist/app/features/sessions/sessions.def.d.ts +141 -0
  16. package/dist/app/features/sessions/sessions.def.js +176 -0
  17. package/dist/app/features/sessions/sessions.run.d.ts +39 -0
  18. package/dist/app/features/sessions/sessions.run.js +58 -0
  19. package/dist/{cli/menu/settings/categories.d.ts → app/features/settings/categories.def.d.ts} +4 -0
  20. package/dist/{cli/menu/settings/categories.js → app/features/settings/categories.def.js} +40 -46
  21. package/dist/app/features/settings/index.d.ts +5 -0
  22. package/dist/app/features/settings/index.js +6 -0
  23. package/dist/{cli/menu/settings/config-file.d.ts → app/features/settings/settings-file.d.ts} +1 -1
  24. package/dist/{cli/menu/settings/config-file.js → app/features/settings/settings-file.js} +1 -1
  25. package/dist/app/features/settings/settings-rows.d.ts +35 -0
  26. package/dist/app/features/settings/settings-rows.js +94 -0
  27. package/dist/app/features/settings/settings.def.d.ts +157 -0
  28. package/dist/app/features/settings/settings.def.js +179 -0
  29. package/dist/app/features/settings/settings.run.d.ts +67 -0
  30. package/dist/app/features/settings/settings.run.js +84 -0
  31. package/dist/app/kernel/define.d.ts +143 -0
  32. package/dist/app/kernel/define.js +42 -0
  33. package/dist/app/kernel/errors.d.ts +34 -0
  34. package/dist/app/kernel/errors.js +45 -0
  35. package/dist/app/kernel/fields.d.ts +70 -0
  36. package/dist/app/kernel/fields.js +243 -0
  37. package/dist/app/kernel/index.d.ts +8 -0
  38. package/dist/app/kernel/index.js +10 -0
  39. package/dist/app/kernel/io.d.ts +193 -0
  40. package/dist/app/kernel/io.js +126 -0
  41. package/dist/app/kernel/rpc.d.ts +156 -0
  42. package/dist/app/kernel/rpc.js +47 -0
  43. package/dist/{cli/menu/settings → app/kernel}/schema-node.d.ts +9 -0
  44. package/dist/{cli/menu/settings → app/kernel}/schema-node.js +26 -0
  45. package/dist/app/kernel/text.d.ts +6 -0
  46. package/dist/app/kernel/text.js +57 -0
  47. package/dist/app/kernel/view.d.ts +146 -0
  48. package/dist/app/kernel/view.js +28 -0
  49. package/dist/app/registry.d.ts +10 -0
  50. package/dist/app/registry.js +50 -0
  51. package/dist/cli/args.d.ts +18 -2
  52. package/dist/cli/args.js +101 -24
  53. package/dist/cli/commands/accounts.js +45 -17
  54. package/dist/cli/commands/context.d.ts +2 -0
  55. package/dist/cli/commands/context.js +9 -2
  56. package/dist/cli/commands/data/clean.js +32 -9
  57. package/dist/cli/commands/engine.d.ts +2 -0
  58. package/dist/cli/commands/engine.js +60 -0
  59. package/dist/cli/commands/index.d.ts +2 -1
  60. package/dist/cli/commands/index.js +2 -1
  61. package/dist/cli/commands/launch/add-root.d.ts +3 -2
  62. package/dist/cli/commands/launch/add-root.js +11 -10
  63. package/dist/cli/commands/launch/launch.js +102 -9
  64. package/dist/cli/commands/launch/prepare.js +6 -4
  65. package/dist/cli/commands/launch/running.js +2 -1
  66. package/dist/cli/commands/launch/summary.d.ts +2 -0
  67. package/dist/cli/commands/maintenance/audit.js +1 -1
  68. package/dist/cli/commands/maintenance/clean.d.ts +1 -1
  69. package/dist/cli/commands/maintenance/clean.js +17 -3
  70. package/dist/cli/commands/maintenance/config-share.d.ts +12 -0
  71. package/dist/cli/commands/maintenance/config-share.js +80 -0
  72. package/dist/cli/commands/maintenance/config.d.ts +1 -1
  73. package/dist/cli/commands/maintenance/config.js +38 -10
  74. package/dist/cli/commands/maintenance/doctor.d.ts +1 -1
  75. package/dist/cli/commands/maintenance/doctor.js +2 -4
  76. package/dist/cli/commands/maintenance/logs.js +14 -0
  77. package/dist/cli/commands/maintenance/migrate.d.ts +2 -1
  78. package/dist/cli/commands/maintenance/migrate.js +19 -4
  79. package/dist/cli/commands/maintenance/sync.js +2 -0
  80. package/dist/cli/commands/maintenance/update.d.ts +2 -0
  81. package/dist/cli/commands/maintenance/update.js +27 -4
  82. package/dist/cli/commands/projects/here.js +12 -7
  83. package/dist/cli/commands/projects/projects.js +26 -17
  84. package/dist/cli/commands/registry.js +10 -7
  85. package/dist/cli/commands/repair/checks/agents.d.ts +2 -0
  86. package/dist/cli/commands/repair/checks/agents.js +70 -0
  87. package/dist/cli/commands/repair/checks/common.d.ts +8 -0
  88. package/dist/cli/commands/repair/checks/common.js +22 -0
  89. package/dist/cli/commands/repair/checks/contained.d.ts +2 -0
  90. package/dist/cli/commands/repair/checks/contained.js +139 -0
  91. package/dist/cli/commands/repair/checks/data.d.ts +2 -0
  92. package/dist/cli/commands/repair/checks/data.js +241 -0
  93. package/dist/cli/commands/repair/checks/hcs.d.ts +7 -0
  94. package/dist/cli/commands/repair/checks/hcs.js +28 -0
  95. package/dist/cli/commands/repair/checks/index.d.ts +2 -0
  96. package/dist/cli/commands/repair/checks/index.js +24 -0
  97. package/dist/cli/commands/repair/checks/install.d.ts +5 -0
  98. package/dist/cli/commands/repair/checks/install.js +318 -0
  99. package/dist/cli/commands/repair/checks/machine.d.ts +2 -0
  100. package/dist/cli/commands/repair/checks/machine.js +232 -0
  101. package/dist/cli/commands/repair/checks/network.d.ts +6 -0
  102. package/dist/cli/commands/repair/checks/network.js +60 -0
  103. package/dist/cli/commands/repair/checks/pc.d.ts +4 -0
  104. package/dist/cli/commands/repair/checks/pc.js +86 -0
  105. package/dist/cli/commands/repair/checks/sandbox.d.ts +2 -0
  106. package/dist/cli/commands/repair/checks/sandbox.js +282 -0
  107. package/dist/cli/commands/repair/checks/settings.d.ts +2 -0
  108. package/dist/cli/commands/repair/checks/settings.js +169 -0
  109. package/dist/cli/commands/repair/checks/vpn.d.ts +2 -0
  110. package/dist/cli/commands/repair/checks/vpn.js +78 -0
  111. package/dist/cli/commands/repair/engine.d.ts +32 -0
  112. package/dist/cli/commands/repair/engine.js +127 -0
  113. package/dist/cli/commands/repair/env.d.ts +7 -0
  114. package/dist/cli/commands/repair/env.js +50 -0
  115. package/dist/cli/commands/repair/index.d.ts +1 -9
  116. package/dist/cli/commands/repair/index.js +2 -54
  117. package/dist/cli/commands/repair/log.d.ts +17 -0
  118. package/dist/cli/commands/repair/log.js +82 -0
  119. package/dist/cli/commands/repair/printer.d.ts +32 -0
  120. package/dist/cli/commands/repair/printer.js +132 -0
  121. package/dist/cli/commands/repair/run.d.ts +33 -0
  122. package/dist/cli/commands/repair/run.js +133 -0
  123. package/dist/cli/commands/repair/types.d.ts +97 -9
  124. package/dist/cli/commands/repair/types.js +11 -7
  125. package/dist/cli/commands/resume.js +2 -2
  126. package/dist/cli/commands/sessions/index.d.ts +0 -4
  127. package/dist/cli/commands/sessions/index.js +3 -7
  128. package/dist/cli/commands/setup/index.d.ts +5 -0
  129. package/dist/cli/commands/setup/index.js +25 -1
  130. package/dist/cli/commands/shared-use.d.ts +5 -2
  131. package/dist/cli/commands/shared-use.js +11 -8
  132. package/dist/cli/commands/storage/contained.d.ts +3 -0
  133. package/dist/cli/commands/storage/contained.js +179 -0
  134. package/dist/cli/commands/storage/index.d.ts +2 -0
  135. package/dist/cli/commands/storage/index.js +2 -0
  136. package/dist/cli/commands/storage/offer.d.ts +3 -0
  137. package/dist/cli/commands/storage/offer.js +91 -0
  138. package/dist/cli/commands/storage/storage.d.ts +8 -0
  139. package/dist/cli/commands/storage/storage.js +179 -0
  140. package/dist/cli/commands/user-config.js +2 -2
  141. package/dist/cli/commands/vpn.d.ts +4 -0
  142. package/dist/cli/commands/vpn.js +91 -0
  143. package/dist/cli/commands/web.d.ts +4 -0
  144. package/dist/cli/commands/web.js +97 -0
  145. package/dist/cli/history.js +1 -1
  146. package/dist/cli/index.js +48 -4
  147. package/dist/cli/manifest.d.ts +339 -97
  148. package/dist/cli/manifest.js +222 -67
  149. package/dist/cli/menu/add-agent.d.ts +47 -0
  150. package/dist/cli/menu/add-agent.js +168 -0
  151. package/dist/cli/menu/apps.d.ts +38 -3
  152. package/dist/cli/menu/apps.js +80 -5
  153. package/dist/cli/menu/command-fields.d.ts +18 -0
  154. package/dist/cli/menu/command-fields.js +61 -0
  155. package/dist/cli/menu/command-form.d.ts +22 -0
  156. package/dist/cli/menu/command-form.js +169 -46
  157. package/dist/cli/menu/data-folder.d.ts +18 -0
  158. package/dist/cli/menu/data-folder.js +99 -0
  159. package/dist/cli/menu/io-menu.d.ts +29 -0
  160. package/dist/cli/menu/io-menu.js +126 -0
  161. package/dist/cli/menu/live.d.ts +27 -0
  162. package/dist/cli/menu/live.js +69 -0
  163. package/dist/cli/menu/memory.d.ts +19 -0
  164. package/dist/cli/menu/memory.js +53 -0
  165. package/dist/cli/menu/menu.d.ts +11 -2
  166. package/dist/cli/menu/menu.js +36 -15
  167. package/dist/cli/menu/pages/accounts-page.js +55 -24
  168. package/dist/cli/menu/pages/agents-page.d.ts +68 -0
  169. package/dist/cli/menu/pages/agents-page.js +345 -0
  170. package/dist/cli/menu/pages/apps-page.d.ts +3 -1
  171. package/dist/cli/menu/pages/apps-page.js +20 -4
  172. package/dist/cli/menu/pages/list-page.d.ts +43 -3
  173. package/dist/cli/menu/pages/list-page.js +146 -12
  174. package/dist/cli/menu/pages/maintenance-page.d.ts +9 -5
  175. package/dist/cli/menu/pages/maintenance-page.js +172 -85
  176. package/dist/cli/menu/pages/sandbox-page.d.ts +7 -6
  177. package/dist/cli/menu/pages/sandbox-page.js +117 -120
  178. package/dist/cli/menu/pages/scopes.d.ts +1 -1
  179. package/dist/cli/menu/pages/sessions-page.d.ts +6 -8
  180. package/dist/cli/menu/pages/sessions-page.js +22 -75
  181. package/dist/cli/menu/pages/settings-page.d.ts +10 -14
  182. package/dist/cli/menu/pages/settings-page.js +95 -102
  183. package/dist/cli/menu/render-view.d.ts +28 -0
  184. package/dist/cli/menu/render-view.js +112 -0
  185. package/dist/cli/menu/settings/ask-path.d.ts +14 -0
  186. package/dist/cli/menu/settings/ask-path.js +14 -0
  187. package/dist/cli/menu/settings/collections/collection-editor.d.ts +8 -2
  188. package/dist/cli/menu/settings/collections/collection-editor.js +12 -8
  189. package/dist/cli/menu/settings/collections/map-editor.js +5 -1
  190. package/dist/cli/menu/settings/collections/object-list-editor.js +2 -2
  191. package/dist/cli/menu/settings/collections/object-map-editor.js +2 -2
  192. package/dist/cli/menu/settings/collections/string-list-editor.d.ts +10 -1
  193. package/dist/cli/menu/settings/collections/string-list-editor.js +23 -0
  194. package/dist/cli/menu/settings/draft.d.ts +1 -1
  195. package/dist/cli/menu/settings/format.d.ts +1 -3
  196. package/dist/cli/menu/settings/format.js +6 -36
  197. package/dist/cli/menu/settings/index.d.ts +1 -3
  198. package/dist/cli/menu/settings/index.js +3 -3
  199. package/dist/cli/menu/settings/object-editor.d.ts +6 -2
  200. package/dist/cli/menu/settings/object-editor.js +15 -4
  201. package/dist/cli/menu/settings/share.d.ts +36 -0
  202. package/dist/cli/menu/settings/share.js +131 -0
  203. package/dist/cli/menu/settings/value-editor.d.ts +10 -1
  204. package/dist/cli/menu/settings/value-editor.js +99 -63
  205. package/dist/cli/menu/several.js +7 -5
  206. package/dist/cli/menu/share-settings.d.ts +21 -0
  207. package/dist/cli/menu/share-settings.js +112 -0
  208. package/dist/cli/menu/shell.d.ts +53 -10
  209. package/dist/cli/menu/shell.js +115 -10
  210. package/dist/cli/menu/views.d.ts +7 -0
  211. package/dist/cli/menu/views.js +11 -0
  212. package/dist/cli/menu/vpn-login.d.ts +16 -0
  213. package/dist/cli/menu/vpn-login.js +74 -0
  214. package/dist/cli/operations/handler.d.ts +6 -0
  215. package/dist/cli/operations/handler.js +61 -0
  216. package/dist/cli/operations/index.d.ts +4 -0
  217. package/dist/cli/operations/index.js +5 -0
  218. package/dist/cli/operations/input.d.ts +6 -0
  219. package/dist/cli/operations/input.js +37 -0
  220. package/dist/cli/operations/io-cli.d.ts +7 -0
  221. package/dist/cli/operations/io-cli.js +62 -0
  222. package/dist/cli/operations/spec.d.ts +18 -0
  223. package/dist/cli/operations/spec.js +108 -0
  224. package/dist/cli/output/colors.d.ts +2 -2
  225. package/dist/cli/output/colors.js +2 -11
  226. package/dist/cli/output/index.d.ts +1 -0
  227. package/dist/cli/output/index.js +1 -0
  228. package/dist/cli/output/print.d.ts +5 -1
  229. package/dist/cli/output/print.js +15 -4
  230. package/dist/cli/output/progress.d.ts +15 -0
  231. package/dist/cli/output/progress.js +44 -0
  232. package/dist/cli/output/render-view.d.ts +4 -0
  233. package/dist/cli/output/render-view.js +63 -0
  234. package/dist/cli/services/accounts-service.d.ts +2 -0
  235. package/dist/cli/services/accounts-service.js +2 -2
  236. package/dist/cli/services/agent-commands-service.d.ts +2 -0
  237. package/dist/cli/services/agent-commands-service.js +11 -2
  238. package/dist/cli/services/health-service.d.ts +0 -6
  239. package/dist/cli/services/health-service.js +5 -42
  240. package/dist/cli/services/index.d.ts +3 -1
  241. package/dist/cli/services/index.js +3 -1
  242. package/dist/cli/services/logs-service.js +4 -3
  243. package/dist/cli/services/migrate-service.js +1 -1
  244. package/dist/cli/services/update-service.d.ts +2 -0
  245. package/dist/cli/services/update-service.js +13 -6
  246. package/dist/cli/services/vpn-service.d.ts +28 -0
  247. package/dist/cli/services/vpn-service.js +46 -0
  248. package/dist/cli/services/web-service.d.ts +22 -0
  249. package/dist/cli/services/web-service.js +111 -0
  250. package/dist/cli/tui/app.d.ts +12 -4
  251. package/dist/cli/tui/app.js +38 -9
  252. package/dist/cli/tui/dialogs/path-listing.d.ts +43 -0
  253. package/dist/cli/tui/dialogs/path-listing.js +127 -0
  254. package/dist/cli/tui/dialogs/path-picker.d.ts +67 -0
  255. package/dist/cli/tui/dialogs/path-picker.js +423 -0
  256. package/dist/cli/tui/dialogs/text-screen.d.ts +6 -0
  257. package/dist/cli/tui/dialogs/text-screen.js +10 -3
  258. package/dist/cli/tui/frame.d.ts +7 -10
  259. package/dist/cli/tui/frame.js +19 -10
  260. package/dist/cli/tui/index.d.ts +4 -3
  261. package/dist/cli/tui/index.js +2 -1
  262. package/dist/cli/tui/list/list-screen.d.ts +28 -2
  263. package/dist/cli/tui/list/list-screen.js +130 -66
  264. package/dist/cli/tui/list/list-types.d.ts +10 -4
  265. package/dist/cli/tui/nav.d.ts +29 -0
  266. package/dist/cli/tui/nav.js +67 -0
  267. package/dist/cli/tui/terminal.d.ts +7 -0
  268. package/dist/cli/tui/terminal.js +30 -10
  269. package/dist/cli/validate.d.ts +1 -1
  270. package/dist/cli/validate.js +3 -3
  271. package/dist/cli/version.d.ts +2 -0
  272. package/dist/cli/version.js +11 -0
  273. package/dist/core/config/defaults.js +13 -1
  274. package/dist/core/config/loader.js +12 -2
  275. package/dist/core/local-config/overrides.js +1 -0
  276. package/dist/core/prompt.d.ts +19 -0
  277. package/dist/core/prompt.js +43 -3
  278. package/dist/core/schema/common.d.ts +6 -0
  279. package/dist/core/schema/common.js +8 -0
  280. package/dist/core/schema/config.d.ts +36 -0
  281. package/dist/core/schema/config.js +26 -2
  282. package/dist/core/schema/harness.d.ts +2 -0
  283. package/dist/core/schema/harness.js +13 -2
  284. package/dist/core/schema/index.d.ts +3 -1
  285. package/dist/core/schema/index.js +3 -1
  286. package/dist/core/schema/profile.d.ts +1 -0
  287. package/dist/core/schema/profile.js +3 -0
  288. package/dist/core/schema/redact.d.ts +13 -0
  289. package/dist/core/schema/redact.js +75 -0
  290. package/dist/core/schema/sandbox.d.ts +6 -0
  291. package/dist/core/schema/sandbox.js +21 -3
  292. package/dist/core/schema/vpn.d.ts +18 -0
  293. package/dist/core/schema/vpn.js +22 -0
  294. package/dist/core/schema/web.d.ts +6 -0
  295. package/dist/core/schema/web.js +14 -0
  296. package/dist/core/types.d.ts +44 -0
  297. package/dist/core/util/fs.d.ts +2 -0
  298. package/dist/core/util/fs.js +9 -0
  299. package/dist/core/util/index.d.ts +1 -1
  300. package/dist/core/util/index.js +1 -1
  301. package/dist/guest/agents/agent-files.d.ts +54 -0
  302. package/dist/guest/agents/agent-files.js +67 -0
  303. package/dist/guest/agents/agent-installer.js +2 -9
  304. package/dist/guest/agents/local-state.d.ts +14 -0
  305. package/dist/guest/agents/local-state.js +218 -0
  306. package/dist/guest/agents/sbx-agent.d.ts +2 -0
  307. package/dist/guest/agents/sbx-agent.js +35 -0
  308. package/dist/guest/boot/boot.d.ts +4 -0
  309. package/dist/guest/boot/boot.js +51 -11
  310. package/dist/guest/daemon/daemon.js +8 -1
  311. package/dist/guest/daemon/exec.js +2 -1
  312. package/dist/guest/daemon/idle-shutdown.js +2 -0
  313. package/dist/guest/daemon/sessions.d.ts +5 -0
  314. package/dist/guest/daemon/sessions.js +20 -3
  315. package/dist/guest/entries/agent.d.ts +1 -0
  316. package/dist/guest/entries/agent.js +10 -0
  317. package/dist/guest/entries/daemon.js +5 -0
  318. package/dist/guest/governor/decide.d.ts +61 -0
  319. package/dist/guest/governor/decide.js +182 -0
  320. package/dist/guest/governor/governor.d.ts +42 -0
  321. package/dist/guest/governor/governor.js +214 -0
  322. package/dist/guest/governor/index.d.ts +2 -0
  323. package/dist/guest/governor/index.js +2 -0
  324. package/dist/guest/runtime/csc.d.ts +2 -0
  325. package/dist/guest/runtime/csc.js +2 -0
  326. package/dist/guest/runtime/secrets.d.ts +12 -0
  327. package/dist/guest/runtime/secrets.js +63 -0
  328. package/dist/guest/sessions/viewer.js +3 -1
  329. package/dist/guest/setup/claude-profile.d.ts +2 -1
  330. package/dist/guest/setup/claude-profile.js +12 -1
  331. package/dist/guest/setup/environment.d.ts +6 -0
  332. package/dist/guest/setup/environment.js +56 -6
  333. package/dist/guest/setup/path-plan.d.ts +32 -0
  334. package/dist/guest/setup/path-plan.js +67 -0
  335. package/dist/guest/setup/shell-path.d.ts +1 -0
  336. package/dist/guest/setup/shell-path.js +22 -0
  337. package/dist/guest/toolchains/languages/python.js +1 -1
  338. package/dist/guest/toolchains/native/rust-extras.js +4 -2
  339. package/dist/guest/toolchains/runtimes.js +2 -2
  340. package/dist/guest/vpn/index.d.ts +1 -0
  341. package/dist/guest/vpn/index.js +1 -0
  342. package/dist/guest/vpn/openvpn.d.ts +9 -0
  343. package/dist/guest/vpn/openvpn.js +47 -0
  344. package/dist/guest/vpn/tunnel.d.ts +17 -0
  345. package/dist/guest/vpn/tunnel.js +78 -0
  346. package/dist/guest/vpn/vpn.d.ts +6 -0
  347. package/dist/guest/vpn/vpn.js +174 -0
  348. package/dist/guest/vpn/wireguard.d.ts +32 -0
  349. package/dist/guest/vpn/wireguard.js +132 -0
  350. package/dist/host/agent-commands/commands.d.ts +4 -0
  351. package/dist/host/agent-commands/commands.js +31 -7
  352. package/dist/host/audit/log.d.ts +1 -1
  353. package/dist/host/channel/attach.d.ts +6 -2
  354. package/dist/host/channel/attach.js +6 -3
  355. package/dist/host/channel/channel.d.ts +9 -0
  356. package/dist/host/channel/channel.js +30 -2
  357. package/dist/host/engines/engine.d.ts +12 -0
  358. package/dist/host/engines/engine.js +1 -0
  359. package/dist/host/engines/hcs/check.d.ts +25 -0
  360. package/dist/host/engines/hcs/check.js +95 -0
  361. package/dist/host/engines/hcs/documents.d.ts +44 -0
  362. package/dist/host/engines/hcs/documents.js +155 -0
  363. package/dist/host/engines/hcs/engine.d.ts +39 -0
  364. package/dist/host/engines/hcs/engine.js +171 -0
  365. package/dist/host/engines/hcs/helper.d.ts +43 -0
  366. package/dist/host/engines/hcs/helper.js +173 -0
  367. package/dist/host/engines/hcs/images.d.ts +37 -0
  368. package/dist/host/engines/hcs/images.js +152 -0
  369. package/dist/host/engines/index.d.ts +7 -0
  370. package/dist/host/engines/index.js +5 -0
  371. package/dist/host/engines/registry.d.ts +16 -0
  372. package/dist/host/engines/registry.js +30 -0
  373. package/dist/host/engines/types.d.ts +58 -0
  374. package/dist/host/engines/types.js +1 -0
  375. package/dist/host/engines/windows-sandbox/engine.d.ts +16 -0
  376. package/dist/host/engines/windows-sandbox/engine.js +63 -0
  377. package/dist/host/engines/windows-sandbox/wsb-text.d.ts +2 -0
  378. package/dist/host/engines/windows-sandbox/wsb-text.js +29 -0
  379. package/dist/host/health/acl-read.d.ts +17 -0
  380. package/dist/host/health/acl-read.js +45 -0
  381. package/dist/host/health/config-backup.d.ts +11 -0
  382. package/dist/host/health/config-backup.js +73 -0
  383. package/dist/host/health/index.d.ts +6 -0
  384. package/dist/host/health/index.js +7 -0
  385. package/dist/host/health/install-state.d.ts +33 -0
  386. package/dist/host/health/install-state.js +110 -0
  387. package/dist/host/health/path-copies.d.ts +32 -0
  388. package/dist/host/health/path-copies.js +82 -0
  389. package/dist/host/health/stale.d.ts +45 -0
  390. package/dist/host/health/stale.js +120 -0
  391. package/dist/host/health/system.d.ts +37 -0
  392. package/dist/host/health/system.js +87 -0
  393. package/dist/host/install/copies.d.ts +13 -0
  394. package/dist/host/install/copies.js +63 -0
  395. package/dist/host/install/index.d.ts +1 -0
  396. package/dist/host/install/index.js +1 -0
  397. package/dist/host/launch/generate.d.ts +5 -1
  398. package/dist/host/launch/generate.js +73 -7
  399. package/dist/host/launch/index.d.ts +3 -1
  400. package/dist/host/launch/index.js +3 -1
  401. package/dist/host/launch/launch-plan.d.ts +13 -0
  402. package/dist/host/launch/launch-plan.js +26 -0
  403. package/dist/host/launch/mappings.js +2 -1
  404. package/dist/host/launch/risk-notes.d.ts +10 -0
  405. package/dist/host/launch/risk-notes.js +18 -0
  406. package/dist/host/launch/session-file.d.ts +2 -0
  407. package/dist/host/launch/session-file.js +11 -2
  408. package/dist/host/launch/stage.js +1 -1
  409. package/dist/host/launch/wsb-file.d.ts +28 -4
  410. package/dist/host/launch/wsb-file.js +61 -42
  411. package/dist/host/life/crash-report.d.ts +27 -1
  412. package/dist/host/life/crash-report.js +173 -7
  413. package/dist/host/life/host-memory.d.ts +40 -0
  414. package/dist/host/life/host-memory.js +137 -0
  415. package/dist/host/life/index.d.ts +2 -0
  416. package/dist/host/life/index.js +2 -0
  417. package/dist/host/life/stop-events.d.ts +2 -0
  418. package/dist/host/life/stop-events.js +20 -3
  419. package/dist/host/life/stop-warning.js +1 -1
  420. package/dist/host/life/watchdog.d.ts +54 -0
  421. package/dist/host/life/watchdog.js +108 -0
  422. package/dist/host/migrate/backup.js +3 -0
  423. package/dist/host/migrate/migrations/config-file.d.ts +2 -0
  424. package/dist/host/migrate/migrations/config-file.js +7 -0
  425. package/dist/host/migrate/migrations/follow-machine-storage.js +9 -1
  426. package/dist/host/migrate/migrations/pin-storage-root.d.ts +4 -0
  427. package/dist/host/migrate/migrations/pin-storage-root.js +46 -0
  428. package/dist/host/migrate/migrations/unpin-config-defaults.js +4 -1
  429. package/dist/host/migrate/registry.js +2 -1
  430. package/dist/host/native.d.ts +3 -2
  431. package/dist/host/native.js +22 -3
  432. package/dist/host/profile/accounts.d.ts +25 -1
  433. package/dist/host/profile/accounts.js +96 -13
  434. package/dist/host/profile/agent-accounts.d.ts +5 -1
  435. package/dist/host/profile/agent-accounts.js +35 -5
  436. package/dist/host/profile/claude-login.js +3 -2
  437. package/dist/host/profile/index.d.ts +2 -1
  438. package/dist/host/profile/index.js +1 -0
  439. package/dist/host/profile/plugin-share.d.ts +26 -0
  440. package/dist/host/profile/plugin-share.js +146 -0
  441. package/dist/host/projects/join.d.ts +7 -1
  442. package/dist/host/projects/join.js +21 -4
  443. package/dist/host/projects/registry.d.ts +16 -10
  444. package/dist/host/projects/registry.js +74 -6
  445. package/dist/host/sandbox/contained-deps.d.ts +2 -0
  446. package/dist/host/sandbox/contained-deps.js +17 -0
  447. package/dist/host/sandbox/index.d.ts +2 -0
  448. package/dist/host/sandbox/index.js +2 -0
  449. package/dist/host/sandbox/platform.d.ts +4 -0
  450. package/dist/host/sandbox/platform.js +23 -4
  451. package/dist/host/sandbox/tasklist.d.ts +13 -0
  452. package/dist/host/sandbox/tasklist.js +47 -0
  453. package/dist/host/secrets/index.d.ts +2 -0
  454. package/dist/host/secrets/index.js +2 -0
  455. package/dist/host/secrets/launch-secrets.d.ts +17 -0
  456. package/dist/host/secrets/launch-secrets.js +94 -0
  457. package/dist/host/secrets/secret-store.d.ts +25 -0
  458. package/dist/host/secrets/secret-store.js +89 -0
  459. package/dist/host/sharing/acl.d.ts +16 -2
  460. package/dist/host/sharing/acl.js +35 -10
  461. package/dist/host/sharing/current.js +8 -3
  462. package/dist/host/sharing/doctor.d.ts +2 -0
  463. package/dist/host/sharing/doctor.js +44 -0
  464. package/dist/host/sharing/group-access.d.ts +6 -0
  465. package/dist/host/sharing/group-access.js +24 -0
  466. package/dist/host/sharing/index.d.ts +2 -1
  467. package/dist/host/sharing/index.js +2 -1
  468. package/dist/host/sharing/lifecycle.d.ts +8 -2
  469. package/dist/host/sharing/lifecycle.js +16 -7
  470. package/dist/host/storage/cleanup.d.ts +2 -0
  471. package/dist/host/storage/cleanup.js +2 -1
  472. package/dist/host/storage/contained/check.d.ts +9 -0
  473. package/dist/host/storage/contained/check.js +37 -0
  474. package/dist/host/storage/contained/contained-storage.d.ts +66 -0
  475. package/dist/host/storage/contained/contained-storage.js +168 -0
  476. package/dist/host/storage/contained/disk-port.d.ts +43 -0
  477. package/dist/host/storage/contained/disk-port.js +122 -0
  478. package/dist/host/storage/contained/index.d.ts +9 -0
  479. package/dist/host/storage/contained/index.js +8 -0
  480. package/dist/host/storage/contained/layout.d.ts +28 -0
  481. package/dist/host/storage/contained/layout.js +45 -0
  482. package/dist/host/storage/contained/resolve.d.ts +4 -0
  483. package/dist/host/storage/contained/resolve.js +30 -0
  484. package/dist/host/storage/contained/setting.d.ts +1 -0
  485. package/dist/host/storage/contained/setting.js +5 -0
  486. package/dist/host/storage/contained/state.d.ts +89 -0
  487. package/dist/host/storage/contained/state.js +166 -0
  488. package/dist/host/storage/contained/transfer.d.ts +24 -0
  489. package/dist/host/storage/contained/transfer.js +121 -0
  490. package/dist/host/storage/history.d.ts +21 -0
  491. package/dist/host/storage/history.js +49 -0
  492. package/dist/host/storage/index.d.ts +6 -0
  493. package/dist/host/storage/index.js +6 -0
  494. package/dist/host/storage/move.d.ts +95 -0
  495. package/dist/host/storage/move.js +384 -0
  496. package/dist/host/storage/offer.d.ts +11 -0
  497. package/dist/host/storage/offer.js +36 -0
  498. package/dist/host/storage/providers/contained.d.ts +15 -0
  499. package/dist/host/storage/providers/contained.js +39 -0
  500. package/dist/host/storage/providers/folder.d.ts +12 -0
  501. package/dist/host/storage/providers/folder.js +20 -0
  502. package/dist/host/storage/providers/index.d.ts +4 -0
  503. package/dist/host/storage/providers/index.js +3 -0
  504. package/dist/host/storage/providers/registry.d.ts +9 -0
  505. package/dist/host/storage/providers/registry.js +14 -0
  506. package/dist/host/storage/providers/types.d.ts +33 -0
  507. package/dist/host/storage/providers/types.js +1 -0
  508. package/dist/host/storage/root.d.ts +18 -0
  509. package/dist/host/storage/root.js +77 -0
  510. package/dist/host/tools/conpty.js +3 -2
  511. package/dist/host/tools/windows-terminal.d.ts +2 -0
  512. package/dist/host/tools/windows-terminal.js +31 -12
  513. package/dist/host/update/index.d.ts +1 -1
  514. package/dist/host/update/index.js +1 -1
  515. package/dist/host/update/notice.d.ts +2 -0
  516. package/dist/host/update/notice.js +13 -1
  517. package/dist/host/update/update-state.d.ts +6 -0
  518. package/dist/host/update/update-state.js +2 -0
  519. package/dist/host/update/updater.d.ts +19 -0
  520. package/dist/host/update/updater.js +88 -12
  521. package/dist/host/vpn/index.d.ts +4 -0
  522. package/dist/host/vpn/index.js +4 -0
  523. package/dist/host/vpn/login.d.ts +24 -0
  524. package/dist/host/vpn/login.js +79 -0
  525. package/dist/host/vpn/nordvpn.d.ts +21 -0
  526. package/dist/host/vpn/nordvpn.js +77 -0
  527. package/dist/host/vpn/prepare.d.ts +19 -0
  528. package/dist/host/vpn/prepare.js +138 -0
  529. package/dist/host/vpn/status.d.ts +12 -0
  530. package/dist/host/vpn/status.js +53 -0
  531. package/dist/host/web/auth.d.ts +38 -0
  532. package/dist/host/web/auth.js +96 -0
  533. package/dist/host/web/backend.d.ts +14 -0
  534. package/dist/host/web/backend.js +1 -0
  535. package/dist/host/web/bridge.d.ts +27 -0
  536. package/dist/host/web/bridge.js +144 -0
  537. package/dist/host/web/browser.d.ts +3 -0
  538. package/dist/host/web/browser.js +23 -0
  539. package/dist/host/web/control.d.ts +17 -0
  540. package/dist/host/web/control.js +67 -0
  541. package/dist/host/web/index.d.ts +10 -0
  542. package/dist/host/web/index.js +9 -0
  543. package/dist/host/web/rpc.d.ts +24 -0
  544. package/dist/host/web/rpc.js +149 -0
  545. package/dist/host/web/runner.d.ts +16 -0
  546. package/dist/host/web/runner.js +44 -0
  547. package/dist/host/web/server.d.ts +47 -0
  548. package/dist/host/web/server.js +238 -0
  549. package/dist/host/web/state.d.ts +20 -0
  550. package/dist/host/web/state.js +41 -0
  551. package/dist/host/web/static-files.d.ts +13 -0
  552. package/dist/host/web/static-files.js +57 -0
  553. package/dist/runtime/agent.js +27675 -0
  554. package/dist/runtime/daemon.js +1950 -1122
  555. package/dist/runtime/db.js +302 -111
  556. package/dist/runtime/main.js +1560 -275
  557. package/dist/runtime/netproxy.js +168 -8
  558. package/dist/runtime/view.js +186 -13
  559. package/dist/selftest/accounts.test.js +40 -0
  560. package/dist/selftest/agent-paths.test.d.ts +2 -0
  561. package/dist/selftest/agent-paths.test.js +125 -0
  562. package/dist/selftest/app.test.d.ts +2 -0
  563. package/dist/selftest/app.test.js +324 -0
  564. package/dist/selftest/channel.test.js +18 -0
  565. package/dist/selftest/cli.test.js +35 -4
  566. package/dist/selftest/config.test.js +59 -0
  567. package/dist/selftest/contained.test.d.ts +2 -0
  568. package/dist/selftest/contained.test.js +544 -0
  569. package/dist/selftest/credentials.test.d.ts +2 -0
  570. package/dist/selftest/credentials.test.js +198 -0
  571. package/dist/selftest/engine.test.d.ts +2 -0
  572. package/dist/selftest/engine.test.js +127 -0
  573. package/dist/selftest/generate.test.js +1 -1
  574. package/dist/selftest/hcs.test.d.ts +2 -0
  575. package/dist/selftest/hcs.test.js +482 -0
  576. package/dist/selftest/health.test.d.ts +2 -0
  577. package/dist/selftest/health.test.js +470 -0
  578. package/dist/selftest/heavy-load.test.d.ts +2 -0
  579. package/dist/selftest/heavy-load.test.js +329 -0
  580. package/dist/selftest/host-sim.test.js +2 -0
  581. package/dist/selftest/index.js +31 -0
  582. package/dist/selftest/layout.test.js +14 -0
  583. package/dist/selftest/menu-perf.test.d.ts +2 -0
  584. package/dist/selftest/menu-perf.test.js +248 -0
  585. package/dist/selftest/menu-screens.d.ts +7 -0
  586. package/dist/selftest/menu-screens.js +68 -17
  587. package/dist/selftest/menu.test.js +603 -22
  588. package/dist/selftest/migrate.test.js +1 -1
  589. package/dist/selftest/personalization.test.js +3 -1
  590. package/dist/selftest/projects.test.js +39 -1
  591. package/dist/selftest/shared-use.test.js +64 -2
  592. package/dist/selftest/sharing.test.js +50 -1
  593. package/dist/selftest/storage.test.d.ts +2 -0
  594. package/dist/selftest/storage.test.js +363 -0
  595. package/dist/selftest/support/engine-cases.d.ts +8 -0
  596. package/dist/selftest/support/engine-cases.js +65 -0
  597. package/dist/selftest/support/engine-golden.d.ts +3 -0
  598. package/dist/selftest/support/engine-golden.js +66 -0
  599. package/dist/selftest/support/fixtures.d.ts +20 -0
  600. package/dist/selftest/support/hcs-probes.d.ts +17 -0
  601. package/dist/selftest/support/hcs-probes.js +41 -0
  602. package/dist/selftest/support/releases.js +1 -1
  603. package/dist/selftest/toolchains.test.js +21 -0
  604. package/dist/selftest/update-service.test.js +87 -3
  605. package/dist/selftest/vpn.test.d.ts +2 -0
  606. package/dist/selftest/vpn.test.js +412 -0
  607. package/dist/selftest/web.test.d.ts +2 -0
  608. package/dist/selftest/web.test.js +402 -0
  609. package/dist/shared/apps/catalogue.js +31 -0
  610. package/dist/shared/channel/index.d.ts +1 -0
  611. package/dist/shared/channel/index.js +1 -0
  612. package/dist/shared/channel/run-dir.d.ts +9 -1
  613. package/dist/shared/channel/run-dir.js +18 -1
  614. package/dist/shared/channel/schema.d.ts +53 -0
  615. package/dist/shared/channel/schema.js +38 -0
  616. package/dist/shared/channel/secrets.d.ts +29 -0
  617. package/dist/shared/channel/secrets.js +50 -0
  618. package/dist/shared/memory/index.d.ts +1 -0
  619. package/dist/shared/memory/index.js +1 -0
  620. package/dist/shared/memory/policy.d.ts +33 -0
  621. package/dist/shared/memory/policy.js +55 -0
  622. package/dist/shared/pty/output-filter.d.ts +14 -1
  623. package/dist/shared/pty/output-filter.js +22 -4
  624. package/dist/shared/pty/terminal.d.ts +4 -1
  625. package/dist/shared/pty/terminal.js +4 -2
  626. package/dist/shared/system.d.ts +1 -0
  627. package/dist/shared/system.js +1 -0
  628. package/dist/shared/vpn/download.d.ts +29 -0
  629. package/dist/shared/vpn/download.js +30 -0
  630. package/dist/shared/vpn/kill-switch.d.ts +18 -0
  631. package/dist/shared/vpn/kill-switch.js +81 -0
  632. package/dist/shared/vpn/ovpn.d.ts +23 -0
  633. package/dist/shared/vpn/ovpn.js +244 -0
  634. package/dist/shared/vpn/wireguard.d.ts +51 -0
  635. package/dist/shared/vpn/wireguard.js +227 -0
  636. package/dist/shared/web/index.d.ts +1 -0
  637. package/dist/shared/web/index.js +1 -0
  638. package/dist/shared/web/protocol.d.ts +61 -0
  639. package/dist/shared/web/protocol.js +35 -0
  640. package/dist/sync/sync-cycle.js +9 -5
  641. package/dist/sync/sync-state.d.ts +1 -0
  642. package/dist/sync/sync-state.js +1 -0
  643. package/dist/sync/watcher.d.ts +13 -0
  644. package/dist/sync/watcher.js +102 -3
  645. package/dist/web/index.html +14 -0
  646. package/dist/web/main-NRRS5O6Z.js +157 -0
  647. package/dist/web/main-T5DMCHYV.css +1 -0
  648. package/native/csharp/FolderSecurity.cs +29 -0
  649. package/native/csharp/HcsHost/AssemblyInfo.cs +14 -0
  650. package/native/csharp/HcsHost/Guard.cs +100 -0
  651. package/native/csharp/HcsHost/Hcs.cs +256 -0
  652. package/native/csharp/HcsHost/Json.cs +78 -0
  653. package/native/csharp/HcsHost/Program.cs +185 -0
  654. package/native/csharp/HcsHost/VirtualDisk.cs +95 -0
  655. package/native/csharp/HostTools/AssemblyInfo.cs +14 -0
  656. package/native/csharp/HostTools/MemoryStatus.cs +107 -0
  657. package/native/csharp/HostTools/Program.cs +58 -17
  658. package/native/scripts/check-contained.ps1 +28 -0
  659. package/native/scripts/contained-common.ps1 +241 -0
  660. package/native/scripts/dismount-contained.ps1 +66 -0
  661. package/native/scripts/memory-status.ps1 +34 -0
  662. package/native/scripts/mount-contained.ps1 +139 -0
  663. package/native/scripts/protect-data.ps1 +29 -0
  664. package/native/scripts/read-folder-sddl.ps1 +10 -0
  665. package/native/scripts/run-elevated.ps1 +17 -4
  666. package/native/scripts/set-folder-access.ps1 +49 -7
  667. package/native/scripts/stop-events.ps1 +23 -8
  668. package/node_modules/ws/LICENSE +20 -0
  669. package/node_modules/ws/README.md +548 -0
  670. package/node_modules/ws/browser.js +8 -0
  671. package/node_modules/ws/index.js +22 -0
  672. package/node_modules/ws/lib/buffer-util.js +131 -0
  673. package/node_modules/ws/lib/constants.js +19 -0
  674. package/node_modules/ws/lib/event-target.js +292 -0
  675. package/node_modules/ws/lib/extension.js +203 -0
  676. package/node_modules/ws/lib/limiter.js +55 -0
  677. package/node_modules/ws/lib/permessage-deflate.js +530 -0
  678. package/node_modules/ws/lib/receiver.js +743 -0
  679. package/node_modules/ws/lib/sender.js +607 -0
  680. package/node_modules/ws/lib/stream.js +161 -0
  681. package/node_modules/ws/lib/subprotocol.js +62 -0
  682. package/node_modules/ws/lib/validation.js +152 -0
  683. package/node_modules/ws/lib/websocket-server.js +562 -0
  684. package/node_modules/ws/lib/websocket.js +1421 -0
  685. package/node_modules/ws/package.json +74 -0
  686. package/node_modules/ws/wrapper.mjs +21 -0
  687. package/package.json +22 -5
  688. package/sandbox/csharp/EnvBroadcast.cs +33 -0
  689. package/sandbox/csharp/MemGov.cs +398 -0
  690. package/sandbox/csharp/PathSync.cs +90 -0
  691. package/sandbox/csharp/PtyHost.cs +111 -5
  692. package/sandbox/scripts/install-shell-path.ps1 +73 -0
  693. package/sandbox/scripts/set-machine-environment.ps1 +37 -4
  694. package/schemas/config.schema.json +136 -7
  695. package/schemas/sandbox-config.schema.json +17 -4
  696. package/dist/cli/commands/repair/checks.d.ts +0 -2
  697. package/dist/cli/commands/repair/checks.js +0 -246
  698. package/dist/cli/commands/sessions/control.d.ts +0 -4
  699. package/dist/cli/commands/sessions/control.js +0 -66
  700. package/dist/cli/commands/sessions/list.d.ts +0 -2
  701. package/dist/cli/commands/sessions/list.js +0 -45
  702. package/dist/cli/commands/sessions/status.d.ts +0 -2
  703. package/dist/cli/commands/sessions/status.js +0 -93
  704. package/dist/cli/commands/sessions/window.d.ts +0 -3
  705. package/dist/cli/commands/sessions/window.js +0 -18
  706. package/dist/cli/menu/pages/start-page.d.ts +0 -43
  707. package/dist/cli/menu/pages/start-page.js +0 -192
  708. package/dist/cli/tui/tab-bar.d.ts +0 -9
  709. package/dist/cli/tui/tab-bar.js +0 -33
@@ -0,0 +1,79 @@
1
+ // The saved VPN login (for NordVPN: the "service credentials", not the account password), kept encrypted with Windows
2
+ // DPAPI in host-only storage (<storage>\vpn\<provider>.json). It is read only when a sandbox starts, to hand to the
3
+ // sandbox in a one-shot file, and is never printed or written anywhere else.
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { z } from 'zod';
7
+ import { JsonFile } from '../../shared/io/index.js';
8
+ import { fail } from '../../core/util/index.js';
9
+ import { VPN_PROVIDERS } from '../../core/schema/index.js';
10
+ import { SecretStore } from '../secrets/index.js';
11
+ const SavedSchema = z.object({
12
+ provider: z.enum(VPN_PROVIDERS),
13
+ savedAt: z.string().max(64),
14
+ sealed: z.string().max(10000),
15
+ });
16
+ /** The login must go on two lines of a file for OpenVPN, so no line breaks or other control characters. */
17
+ export function loginProblem(c) {
18
+ const clean = (v) => !/[\u0000-\u001f\u007f]/.test(v);
19
+ if (!c.username.trim() || !c.password)
20
+ return 'Both the user name and the password are needed.';
21
+ if (!clean(c.username) || !clean(c.password))
22
+ return 'The login may not contain line breaks or control characters.';
23
+ if (c.username.length > 256 || c.password.length > 1024)
24
+ return 'The user name or password is too long.';
25
+ return null;
26
+ }
27
+ export class VpnLogin {
28
+ storageRoot;
29
+ secrets;
30
+ constructor(storageRoot, secrets = SecretStore.standard()) {
31
+ this.storageRoot = storageRoot;
32
+ this.secrets = secrets;
33
+ }
34
+ file(provider) {
35
+ return new JsonFile(SavedSchema, path.join(this.storageRoot, 'vpn', provider + '.json'));
36
+ }
37
+ /** Encrypts and saves the login (replacing an earlier one). */
38
+ save(provider, login) {
39
+ const problem = loginProblem(login);
40
+ if (problem)
41
+ fail(problem, 'Type the service credentials again.');
42
+ this.file(provider).write({
43
+ provider,
44
+ savedAt: new Date().toISOString(),
45
+ sealed: this.secrets.sealJson({ username: login.username.trim(), password: login.password }),
46
+ });
47
+ }
48
+ /** The login, decrypted. Only the launch calls this. */
49
+ read(provider) {
50
+ const saved = this.file(provider).read();
51
+ if (!saved)
52
+ return null;
53
+ const value = this.secrets.openJson(saved.sealed);
54
+ if (typeof value.username !== 'string' || typeof value.password !== 'string')
55
+ fail('The saved VPN login is damaged.', 'Save it again with: sandbox vpn login');
56
+ return { username: value.username, password: value.password };
57
+ }
58
+ /** Whether a login is saved and can be decrypted by this Windows user (the values are never returned). */
59
+ state(provider) {
60
+ if (!this.file(provider).read())
61
+ return 'none';
62
+ try {
63
+ return this.read(provider) ? 'saved' : 'none';
64
+ }
65
+ catch {
66
+ return 'unreadable';
67
+ }
68
+ }
69
+ savedAt(provider) {
70
+ return this.file(provider).read()?.savedAt ?? null;
71
+ }
72
+ remove(provider) {
73
+ const file = this.file(provider).file;
74
+ if (!fs.existsSync(file))
75
+ return false;
76
+ fs.rmSync(file, { force: true });
77
+ return true;
78
+ }
79
+ }
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ /** Reads a URL as text, refusing more than `max` bytes (a server cannot make this PC download without end). */
3
+ export type Fetcher = (url: string, max: number) => Promise<string>;
4
+ export declare function fetchBounded(url: string, max: number): Promise<string>;
5
+ declare const CountriesSchema: z.ZodArray<z.ZodObject<{
6
+ id: z.ZodNumber;
7
+ name: z.ZodString;
8
+ code: z.ZodString;
9
+ }, z.core.$strip>>;
10
+ export interface NordServer {
11
+ /** e.g. uk2201.nordvpn.com */
12
+ readonly hostname: string;
13
+ readonly ip: string;
14
+ }
15
+ /** The country's id at NordVPN for what was typed (code or name, any case); fails listing nothing it cannot back up. */
16
+ export declare function findCountry(countries: z.output<typeof CountriesSchema>, typed: string): number;
17
+ /** The recommended server for the country (or anywhere) and protocol. */
18
+ export declare function recommendedServer(protocol: 'udp' | 'tcp', country: string, fetchText?: Fetcher): Promise<NordServer>;
19
+ /** The server's OpenVPN profile (not yet checked: shared/vpn/ovpn.ts does that). */
20
+ export declare function nordProfile(server: NordServer, protocol: 'udp' | 'tcp', fetchText?: Fetcher): Promise<string>;
21
+ export {};
@@ -0,0 +1,77 @@
1
+ // Picks a NordVPN server at launch from NordVPN's public server API and fetches its OpenVPN profile. Done on this PC,
2
+ // not in the sandbox: the sandbox's firewall then needs no hole for the API or the download host, and what comes back
3
+ // is checked here (bounded size, strict shapes, shared/vpn/ovpn.ts) before the sandbox gets it. Nothing here needs
4
+ // the login: the profiles are public.
5
+ import { z } from 'zod';
6
+ import { fetchRetry } from '../../shared/download/index.js';
7
+ import { fail } from '../../core/util/index.js';
8
+ import { MAX_OVPN_BYTES } from '../../shared/vpn/ovpn.js';
9
+ const API = 'https://api.nordvpn.com/v1';
10
+ const CONFIGS = 'https://downloads.nordcdn.com/configs/files';
11
+ const MAX_JSON_BYTES = 2 * 1024 * 1024;
12
+ export async function fetchBounded(url, max) {
13
+ const response = await fetchRetry(url, {}, 2, 30000);
14
+ const length = Number(response.headers.get('content-length')) || 0;
15
+ if (length > max)
16
+ throw new Error('The answer from ' + new URL(url).host + ' is too big.');
17
+ const reader = response.body?.getReader();
18
+ if (!reader)
19
+ throw new Error('Empty answer from ' + new URL(url).host + '.');
20
+ const chunks = [];
21
+ let size = 0;
22
+ for (;;) {
23
+ const { done, value } = await reader.read();
24
+ if (done)
25
+ break;
26
+ size += value.length;
27
+ if (size > max) {
28
+ await reader.cancel();
29
+ throw new Error('The answer from ' + new URL(url).host + ' is too big.');
30
+ }
31
+ chunks.push(value);
32
+ }
33
+ return Buffer.concat(chunks).toString('utf8');
34
+ }
35
+ const CountriesSchema = z
36
+ .array(z.object({ id: z.number().int(), name: z.string().max(100), code: z.string().max(4) }))
37
+ .max(400);
38
+ const ServersSchema = z
39
+ .array(z.object({
40
+ hostname: z.string().regex(/^[a-z0-9-]{2,40}\.nordvpn\.com$/),
41
+ station: z.string().regex(/^\d{1,3}(\.\d{1,3}){3}$/),
42
+ }))
43
+ .max(50);
44
+ /** Names people type that NordVPN spells differently. */
45
+ const COUNTRY_ALIASES = {
46
+ uk: 'gb',
47
+ 'united kingdom': 'gb',
48
+ usa: 'us',
49
+ america: 'us',
50
+ };
51
+ /** The country's id at NordVPN for what was typed (code or name, any case); fails listing nothing it cannot back up. */
52
+ export function findCountry(countries, typed) {
53
+ const want = typed.trim().toLowerCase();
54
+ const alias = COUNTRY_ALIASES[want] ?? want;
55
+ const found = countries.find((c) => c.code.toLowerCase() === alias || c.name.toLowerCase() === alias);
56
+ if (!found)
57
+ fail('NordVPN has no country "' + typed + '".', 'Use a name like Germany or a code like de (vpn.country in your settings), or leave it empty.');
58
+ return found.id;
59
+ }
60
+ /** The recommended server for the country (or anywhere) and protocol. */
61
+ export async function recommendedServer(protocol, country, fetchText = fetchBounded) {
62
+ const filters = ['filters[servers_technologies][identifier]=openvpn_' + protocol, 'limit=1'];
63
+ if (country.trim()) {
64
+ const countries = CountriesSchema.safeParse(JSON.parse(await fetchText(API + '/servers/countries', MAX_JSON_BYTES)));
65
+ if (!countries.success)
66
+ fail("NordVPN's list of countries was not in the expected form.", 'Try again later.');
67
+ filters.push('filters[country_id]=' + findCountry(countries.data, country));
68
+ }
69
+ const answer = ServersSchema.safeParse(JSON.parse(await fetchText(API + '/servers/recommendations?' + filters.join('&'), MAX_JSON_BYTES)));
70
+ if (!answer.success || answer.data.length === 0)
71
+ fail('NordVPN did not recommend a server' + (country.trim() ? ' in ' + country.trim() : '') + '.', 'Try another country (vpn.country), or leave it empty.');
72
+ return { hostname: answer.data[0].hostname, ip: answer.data[0].station };
73
+ }
74
+ /** The server's OpenVPN profile (not yet checked: shared/vpn/ovpn.ts does that). */
75
+ export function nordProfile(server, protocol, fetchText = fetchBounded) {
76
+ return fetchText(CONFIGS + '/ovpn_' + protocol + '/servers/' + server.hostname + '.' + protocol + '.ovpn', MAX_OVPN_BYTES);
77
+ }
@@ -0,0 +1,19 @@
1
+ import type { Config, PreparedVpn } from '../../core/types.js';
2
+ import { type Fetcher } from './nordvpn.js';
3
+ import { VpnLogin } from './login.js';
4
+ export interface PrepareOptions {
5
+ readonly config: Config;
6
+ readonly storageRoot: string;
7
+ /** A sandbox is running: the login is not handed to anything that is not being started now. */
8
+ readonly sandboxRunning?: boolean;
9
+ readonly login?: VpnLogin;
10
+ readonly fetchText?: Fetcher;
11
+ /** Folder a relative vpn.configFile is relative to. */
12
+ readonly base?: string;
13
+ }
14
+ /** Null when the VPN is off. Throws a UserError that says what to do when it cannot be set up. */
15
+ export declare function prepareVpn(o: PrepareOptions): Promise<PreparedVpn | null>;
16
+ /** For doctor: null when vpn.configFile is a readable, safe WireGuard config, else a short reason (never a key). */
17
+ export declare function wireguardFileProblem(configFile: string, base: string): string | null;
18
+ /** What the launch says about the VPN: the warnings the user must see before trusting it. */
19
+ export declare function vpnNotes(vpn: Config['vpn']): string[];
@@ -0,0 +1,138 @@
1
+ // What a launch needs for the VPN: the saved login, a server and its profile, the profile checked. Nothing is written
2
+ // here; generateSandbox puts the profile in the launch folder and the login in the one-shot secrets file.
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { expandPath, fail } from '../../core/util/index.js';
6
+ import { assertSafeOvpn, MAX_OVPN_BYTES } from '../../shared/vpn/ovpn.js';
7
+ import { assertSafeWireguard, inspectWireguard, MAX_WIREGUARD_BYTES, renderWireguard, } from '../../shared/vpn/wireguard.js';
8
+ import { fetchBounded, nordProfile, recommendedServer } from './nordvpn.js';
9
+ import { VpnLogin } from './login.js';
10
+ /** Null when the VPN is off. Throws a UserError that says what to do when it cannot be set up. */
11
+ export async function prepareVpn(o) {
12
+ const { vpn } = o.config;
13
+ if (!vpn.enabled)
14
+ return null;
15
+ if (!o.config.sandbox.networking)
16
+ fail('The VPN is on, but sandbox.networking is off: there is no network to put it on.', 'Turn one of them off.');
17
+ if (o.sandboxRunning)
18
+ fail('A sandbox is running already, so the VPN login is not handed over.', 'Start the VPN sandbox after it stops.');
19
+ if (vpn.provider === 'wireguard-file')
20
+ return prepareWireguard(o);
21
+ const login = o.login ?? new VpnLogin(o.storageRoot);
22
+ const credentials = login.read(vpn.provider) ??
23
+ fail('The VPN is on, but no ' + (vpn.provider === 'nordvpn' ? 'NordVPN' : 'VPN') + ' login is saved.', 'Save it with: sandbox vpn login (or turn the VPN off: sandbox config set vpn.enabled false)');
24
+ let profile;
25
+ let server;
26
+ if (vpn.provider === 'nordvpn') {
27
+ const fetchText = o.fetchText ?? fetchBounded;
28
+ try {
29
+ const picked = await recommendedServer(vpn.protocol, vpn.country, fetchText);
30
+ server = picked.hostname;
31
+ profile = await nordProfile(picked, vpn.protocol, fetchText);
32
+ }
33
+ catch (e) {
34
+ if (e instanceof Error && e.name === 'UserError')
35
+ throw e;
36
+ fail('Could not get a NordVPN server: ' + (e instanceof Error ? e.message : String(e)), 'Check this PC is online, or turn the VPN off for now: sandbox config set vpn.enabled false');
37
+ }
38
+ }
39
+ else {
40
+ if (!vpn.configFile.trim())
41
+ fail('vpn.provider is openvpn-file but vpn.configFile is empty.', 'Set it: sandbox config set vpn.configFile <path>');
42
+ const file = expandPath(vpn.configFile, o.base ?? process.cwd());
43
+ if (!fs.existsSync(file) || !fs.statSync(file).isFile())
44
+ fail('The VPN profile ' + file + ' does not exist.', 'Fix vpn.configFile.');
45
+ if (fs.statSync(file).size > MAX_OVPN_BYTES)
46
+ fail('The VPN profile ' + file + ' is too big.', 'Use a plain .ovpn file.');
47
+ profile = fs.readFileSync(file, 'utf8');
48
+ server = path.basename(file);
49
+ }
50
+ try {
51
+ assertSafeOvpn(profile, server);
52
+ }
53
+ catch (e) {
54
+ fail(e instanceof Error ? e.message : String(e), 'Nothing was started. Use a profile without script or plugin lines.');
55
+ }
56
+ return {
57
+ session: {
58
+ provider: vpn.provider,
59
+ protocol: vpn.protocol,
60
+ killSwitch: vpn.killSwitch,
61
+ server,
62
+ profile: 'vpn\\server.ovpn',
63
+ },
64
+ profile,
65
+ credentials,
66
+ };
67
+ }
68
+ /**
69
+ * wireguard-file: reads vpn.configFile on this PC (size capped), checks it as untrusted data and returns it written
70
+ * again from the checked values. It holds the private key, so it only ever goes in the one-shot secrets file. There is
71
+ * no saved login: the keys are in the file.
72
+ */
73
+ function prepareWireguard(o) {
74
+ const { vpn } = o.config;
75
+ if (!vpn.configFile.trim())
76
+ fail('vpn.provider is wireguard-file but vpn.configFile is empty.', 'Set it: sandbox config set vpn.configFile <path to your .conf>');
77
+ const file = expandPath(vpn.configFile, o.base ?? process.cwd());
78
+ let size;
79
+ try {
80
+ const stat = fs.statSync(file);
81
+ if (!stat.isFile())
82
+ throw new Error('not a file');
83
+ size = stat.size;
84
+ }
85
+ catch {
86
+ return fail('The WireGuard config ' + file + ' does not exist.', 'Fix vpn.configFile.');
87
+ }
88
+ if (size > MAX_WIREGUARD_BYTES)
89
+ fail('The WireGuard config ' + file + ' is too big.', 'Use a plain .conf file.');
90
+ const text = fs.readFileSync(file, 'utf8');
91
+ try {
92
+ const config = assertSafeWireguard(text, path.basename(file));
93
+ return {
94
+ session: { provider: vpn.provider, protocol: 'udp', killSwitch: vpn.killSwitch, server: path.basename(file) },
95
+ wireguardConfig: renderWireguard(config),
96
+ };
97
+ }
98
+ catch (e) {
99
+ return fail(e instanceof Error ? e.message : String(e), 'Nothing was started. Use a config without PostUp, PreUp or other script lines.');
100
+ }
101
+ }
102
+ /** For doctor: null when vpn.configFile is a readable, safe WireGuard config, else a short reason (never a key). */
103
+ export function wireguardFileProblem(configFile, base) {
104
+ if (!configFile.trim())
105
+ return 'vpn.configFile is empty';
106
+ const file = expandPath(configFile, base);
107
+ try {
108
+ const stat = fs.statSync(file);
109
+ if (!stat.isFile())
110
+ return file + ' is not a file';
111
+ if (stat.size > MAX_WIREGUARD_BYTES)
112
+ return file + ' is too big for a WireGuard config';
113
+ const report = inspectWireguard(fs.readFileSync(file, 'utf8'));
114
+ return report.ok ? null : 'refused: ' + report.problems.slice(0, 3).join('; ');
115
+ }
116
+ catch {
117
+ return file + ' cannot be read';
118
+ }
119
+ }
120
+ /** What the launch says about the VPN: the warnings the user must see before trusting it. */
121
+ export function vpnNotes(vpn) {
122
+ if (!vpn.enabled)
123
+ return [];
124
+ return [
125
+ 'VPN: ' +
126
+ (vpn.provider === 'nordvpn'
127
+ ? 'NordVPN' + (vpn.country ? ' (' + vpn.country + ')' : '')
128
+ : vpn.provider === 'wireguard-file'
129
+ ? 'your WireGuard config'
130
+ : 'your profile') +
131
+ (vpn.killSwitch
132
+ ? ', kill switch on: if the tunnel fails the sandbox stays offline.'
133
+ : ', kill switch OFF: if the tunnel fails the sandbox uses your normal connection.'),
134
+ vpn.provider === 'wireguard-file'
135
+ ? 'The agent in the sandbox can read the WireGuard private key from your config and can turn the tunnel off, because it is the administrator there. Use a key you can revoke.'
136
+ : 'The agent in the sandbox can read the VPN login (a service login you can revoke) and can turn the tunnel off, because it is the administrator there.',
137
+ ];
138
+ }
@@ -0,0 +1,12 @@
1
+ import { type VpnStatus } from '../../shared/channel/index.js';
2
+ import { type Fetcher } from './nordvpn.js';
3
+ export interface VpnLine {
4
+ readonly level: 'ok' | 'warn' | 'bad';
5
+ readonly text: string;
6
+ }
7
+ /** This PC's own public address (one small request), or null when it cannot be told. */
8
+ export declare function hostPublicIp(fetchText?: Fetcher): Promise<string | null>;
9
+ /** One line for the status the sandbox reported (text from the sandbox is made safe first). */
10
+ export declare function vpnLine(status: VpnStatus | null, hostIp?: string | null): VpnLine;
11
+ /** The running sandbox's VPN line, or null when its VPN was never on (no status file). */
12
+ export declare function readVpnLine(dataPath: string, hostIp?: string | null): VpnLine | null;
@@ -0,0 +1,53 @@
1
+ // What the host says about a running sandbox's VPN, from the status the sandbox writes (run\vpn.json, validated).
2
+ import { RunDir } from '../../shared/channel/index.js';
3
+ import { safeText } from '../../core/util/index.js';
4
+ import { fetchBounded } from './nordvpn.js';
5
+ /** This PC's own public address (one small request), or null when it cannot be told. */
6
+ export async function hostPublicIp(fetchText = fetchBounded) {
7
+ try {
8
+ const ip = (await fetchText('https://api.ipify.org', 64)).trim();
9
+ return /^[0-9a-fA-F.:]{3,45}$/.test(ip) ? ip : null;
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ }
15
+ /** One line for the status the sandbox reported (text from the sandbox is made safe first). */
16
+ export function vpnLine(status, hostIp = null) {
17
+ if (!status)
18
+ return { level: 'warn', text: 'The sandbox has not reported on the VPN.' };
19
+ const message = safeText(status.message).slice(0, 300);
20
+ if (status.state === 'up') {
21
+ const same = hostIp !== null && status.publicIp === hostIp;
22
+ return same
23
+ ? {
24
+ level: 'bad',
25
+ text: "VPN reports up, but the sandbox shows this PC's own address (" +
26
+ hostIp +
27
+ '): the traffic is not going through it.',
28
+ }
29
+ : {
30
+ level: 'ok',
31
+ text: 'VPN up' +
32
+ (status.server ? ' (' + safeText(status.server) + ')' : '') +
33
+ (status.publicIp ? ', the sandbox appears as ' + safeText(status.publicIp) : '') +
34
+ (hostIp && status.publicIp ? ' (this PC: ' + hostIp + ')' : '') +
35
+ '.',
36
+ };
37
+ }
38
+ if (status.state === 'failed')
39
+ return {
40
+ level: 'bad',
41
+ text: 'VPN failed: ' +
42
+ message +
43
+ (status.killSwitch
44
+ ? ' The kill switch is on, so the sandbox has no internet.'
45
+ : ' The kill switch is off, so the sandbox uses your normal connection.'),
46
+ };
47
+ return { level: 'warn', text: 'VPN ' + status.state + (message ? ': ' + message : '') };
48
+ }
49
+ /** The running sandbox's VPN line, or null when its VPN was never on (no status file). */
50
+ export function readVpnLine(dataPath, hostIp = null) {
51
+ const status = new RunDir(dataPath).readVpnStatus();
52
+ return status && status.state !== 'off' ? vpnLine(status, hostIp) : null;
53
+ }
@@ -0,0 +1,38 @@
1
+ /** A cookie lives this long without being used again. */
2
+ export declare const COOKIE_LIFETIME_MS: number;
3
+ /** Most signed-in browsers at once. */
4
+ export declare const MAX_COOKIES = 50;
5
+ /** This many wrong tokens within the window locks logging in until the window has passed. */
6
+ export declare const MAX_FAILURES = 8;
7
+ export declare const FAILURE_WINDOW_MS: number;
8
+ export declare function newToken(): string;
9
+ /** Compares two secrets without leaking where they differ (the digests have the same length). */
10
+ export declare function sameSecret(a: string, b: string): boolean;
11
+ /** The Host header must name this PC's loopback and our port: anything else is DNS rebinding or a mistake. */
12
+ export declare function hostAllowed(host: string | undefined, port: number): boolean;
13
+ /** An Origin header (when there is one) must be our own page. */
14
+ export declare function originAllowed(origin: string | undefined, host: string | undefined, port: number): boolean;
15
+ /** State-changing calls need the custom header; a form or a no-CORS request from another site cannot send it. */
16
+ export declare function csrfOk(headers: Readonly<Record<string, string | string[] | undefined>>): boolean;
17
+ export declare function cookieValue(header: string | undefined, name?: string): string | undefined;
18
+ export type LoginResult = {
19
+ readonly ok: true;
20
+ readonly cookie: string;
21
+ } | {
22
+ readonly ok: false;
23
+ readonly status: 401 | 429;
24
+ };
25
+ export declare class WebAuth {
26
+ private readonly token;
27
+ private readonly now;
28
+ private readonly cookies;
29
+ private failures;
30
+ constructor(token: string, now?: () => number);
31
+ /** Trades the token for a new cookie value; wrong tokens are counted, and too many lock this for a minute. */
32
+ login(candidate: unknown): LoginResult;
33
+ /** The request's Cookie header carries a signed-in browser's cookie (and renews it). */
34
+ signedIn(cookieHeader: string | undefined): boolean;
35
+ private expire;
36
+ }
37
+ /** The Set-Cookie value: not readable by scripts, never sent by another site. */
38
+ export declare function cookieHeader(value: string): string;
@@ -0,0 +1,96 @@
1
+ // Who may talk to the web UI's server: the token trade, the session cookie, and the checks that stop other sites (and
2
+ // other names for this PC) from driving it. Pure apart from the clock and the random source (self-test covers it).
3
+ import crypto from 'node:crypto';
4
+ import { COOKIE_NAME, CSRF_HEADER, CSRF_VALUE } from '../../shared/web/index.js';
5
+ /** A cookie lives this long without being used again. */
6
+ export const COOKIE_LIFETIME_MS = 12 * 60 * 60 * 1000;
7
+ /** Most signed-in browsers at once. */
8
+ export const MAX_COOKIES = 50;
9
+ /** This many wrong tokens within the window locks logging in until the window has passed. */
10
+ export const MAX_FAILURES = 8;
11
+ export const FAILURE_WINDOW_MS = 60 * 1000;
12
+ export function newToken() {
13
+ return crypto.randomBytes(32).toString('hex');
14
+ }
15
+ /** Compares two secrets without leaking where they differ (the digests have the same length). */
16
+ export function sameSecret(a, b) {
17
+ const x = crypto.createHash('sha256').update(a).digest();
18
+ const y = crypto.createHash('sha256').update(b).digest();
19
+ return crypto.timingSafeEqual(x, y);
20
+ }
21
+ /** The Host header must name this PC's loopback and our port: anything else is DNS rebinding or a mistake. */
22
+ export function hostAllowed(host, port) {
23
+ return host === '127.0.0.1:' + port || host === 'localhost:' + port;
24
+ }
25
+ /** An Origin header (when there is one) must be our own page. */
26
+ export function originAllowed(origin, host, port) {
27
+ return host !== undefined && hostAllowed(host, port) && origin === 'http://' + host;
28
+ }
29
+ /** State-changing calls need the custom header; a form or a no-CORS request from another site cannot send it. */
30
+ export function csrfOk(headers) {
31
+ return headers[CSRF_HEADER] === CSRF_VALUE;
32
+ }
33
+ export function cookieValue(header, name = COOKIE_NAME) {
34
+ if (!header)
35
+ return undefined;
36
+ for (const part of header.split(';')) {
37
+ const eq = part.indexOf('=');
38
+ if (eq > 0 && part.slice(0, eq).trim() === name)
39
+ return part.slice(eq + 1).trim();
40
+ }
41
+ return undefined;
42
+ }
43
+ export class WebAuth {
44
+ token;
45
+ now;
46
+ cookies = new Map();
47
+ failures = [];
48
+ constructor(token, now = Date.now) {
49
+ this.token = token;
50
+ this.now = now;
51
+ }
52
+ /** Trades the token for a new cookie value; wrong tokens are counted, and too many lock this for a minute. */
53
+ login(candidate) {
54
+ const t = this.now();
55
+ this.failures = this.failures.filter((at) => t - at < FAILURE_WINDOW_MS);
56
+ if (this.failures.length >= MAX_FAILURES)
57
+ return { ok: false, status: 429 };
58
+ if (typeof candidate !== 'string' || candidate.length > 256 || !sameSecret(candidate, this.token)) {
59
+ this.failures.push(t);
60
+ return { ok: false, status: 401 };
61
+ }
62
+ this.expire(t);
63
+ if (this.cookies.size >= MAX_COOKIES) {
64
+ const oldest = [...this.cookies.entries()].sort((a, b) => a[1] - b[1])[0];
65
+ if (oldest)
66
+ this.cookies.delete(oldest[0]);
67
+ }
68
+ const cookie = crypto.randomBytes(32).toString('hex');
69
+ this.cookies.set(cookie, t);
70
+ return { ok: true, cookie };
71
+ }
72
+ /** The request's Cookie header carries a signed-in browser's cookie (and renews it). */
73
+ signedIn(cookieHeader) {
74
+ const value = cookieValue(cookieHeader);
75
+ if (!value)
76
+ return false;
77
+ const t = this.now();
78
+ this.expire(t);
79
+ for (const known of this.cookies.keys()) {
80
+ if (known.length === value.length && sameSecret(known, value)) {
81
+ this.cookies.set(known, t);
82
+ return true;
83
+ }
84
+ }
85
+ return false;
86
+ }
87
+ expire(t) {
88
+ for (const [cookie, last] of this.cookies)
89
+ if (t - last > COOKIE_LIFETIME_MS)
90
+ this.cookies.delete(cookie);
91
+ }
92
+ }
93
+ /** The Set-Cookie value: not readable by scripts, never sent by another site. */
94
+ export function cookieHeader(value) {
95
+ return COOKIE_NAME + '=' + value + '; Path=/; HttpOnly; SameSite=Strict; Max-Age=' + COOKIE_LIFETIME_MS / 1000;
96
+ }
@@ -0,0 +1,14 @@
1
+ import type { Endpoint } from '../../shared/pty/index.js';
2
+ import type { NewSessionRequest, WebInfo, WebSession } from '../../shared/web/index.js';
3
+ export interface WebBackend {
4
+ info(): Promise<WebInfo>;
5
+ /** Sessions as the browser may see them: never an attach token or address. */
6
+ sessions(): Promise<WebSession[]>;
7
+ /**
8
+ * Where to connect to a session's terminal (with its token, which stays on this PC), or null when there is no such
9
+ * running session, the sandbox is not shared with this user, or it has no address on this PC's sandbox network.
10
+ */
11
+ endpoint(sessionId: string): Endpoint | null;
12
+ /** Starts an agent in a project of the running sandbox and waits until it runs. */
13
+ create(request: NewSessionRequest): Promise<WebSession>;
14
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import type net from 'node:net';
2
+ import type { WebSocket } from 'ws';
3
+ import { type Endpoint } from '../../shared/pty/index.js';
4
+ export declare class TerminalBridge {
5
+ private readonly ws;
6
+ private readonly endpoint;
7
+ private readonly cols;
8
+ private readonly rows;
9
+ private readonly dial;
10
+ private socket;
11
+ private pinger;
12
+ private drain;
13
+ private stalledSince;
14
+ private done;
15
+ private readonly filter;
16
+ private readonly reader;
17
+ constructor(ws: WebSocket, endpoint: Endpoint, cols: number, rows: number, dial?: (endpoint: Endpoint) => Promise<net.Socket>);
18
+ /** Connects to the session and starts passing data both ways. */
19
+ start(): Promise<void>;
20
+ private fromBrowser;
21
+ private fromSession;
22
+ /** Stops reading from the session until the browser has taken what it was sent. */
23
+ private hold;
24
+ private tell;
25
+ /** Closes both sides (once). */
26
+ private finish;
27
+ }