windows-development-sandbox 1.4.0 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (877) hide show
  1. package/.sandbox-config.example.json +2 -1
  2. package/config.example.json +4 -1
  3. package/dist/api.js +27 -16
  4. package/dist/cli/args.d.ts +4 -6
  5. package/dist/cli/args.js +67 -34
  6. package/dist/cli/argv.d.ts +9 -0
  7. package/dist/cli/argv.js +22 -0
  8. package/dist/cli/commands/accounts.d.ts +1 -1
  9. package/dist/cli/commands/accounts.js +42 -27
  10. package/dist/cli/commands/agent-commands.d.ts +3 -3
  11. package/dist/cli/commands/agent-commands.js +27 -18
  12. package/dist/cli/commands/context.d.ts +9 -11
  13. package/dist/cli/commands/context.js +35 -32
  14. package/dist/cli/commands/data/clean.d.ts +2 -2
  15. package/dist/cli/commands/data/clean.js +27 -11
  16. package/dist/cli/commands/data/collect.d.ts +6 -3
  17. package/dist/cli/commands/data/collect.js +46 -15
  18. package/dist/cli/commands/data/index.d.ts +2 -2
  19. package/dist/cli/commands/data/index.js +30 -12
  20. package/dist/cli/commands/data/remove.d.ts +1 -1
  21. package/dist/cli/commands/data/remove.js +4 -4
  22. package/dist/cli/commands/index.d.ts +5 -4
  23. package/dist/cli/commands/index.js +5 -4
  24. package/dist/cli/commands/launch/add-root.d.ts +7 -0
  25. package/dist/cli/commands/launch/add-root.js +64 -0
  26. package/dist/cli/commands/launch/boot-progress.d.ts +7 -0
  27. package/dist/cli/commands/launch/boot-progress.js +48 -0
  28. package/dist/cli/commands/launch/boot-wants.d.ts +11 -0
  29. package/dist/cli/commands/launch/boot-wants.js +48 -0
  30. package/dist/cli/commands/launch/first-start.d.ts +10 -0
  31. package/dist/cli/commands/launch/first-start.js +53 -0
  32. package/dist/cli/commands/launch/index.d.ts +6 -0
  33. package/dist/cli/commands/launch/index.js +6 -0
  34. package/dist/cli/commands/launch/launch.d.ts +8 -0
  35. package/dist/cli/commands/launch/launch.js +211 -0
  36. package/dist/cli/commands/launch/prepare.d.ts +23 -0
  37. package/dist/cli/commands/launch/prepare.js +109 -0
  38. package/dist/cli/commands/launch/running.d.ts +45 -0
  39. package/dist/cli/commands/launch/running.js +218 -0
  40. package/dist/cli/commands/launch/summary.d.ts +8 -0
  41. package/dist/cli/commands/launch/summary.js +98 -0
  42. package/dist/cli/commands/maintenance/audit.d.ts +3 -0
  43. package/dist/cli/commands/maintenance/audit.js +58 -0
  44. package/dist/cli/commands/maintenance/clean.d.ts +2 -0
  45. package/dist/cli/commands/maintenance/clean.js +10 -0
  46. package/dist/cli/commands/maintenance/config.d.ts +2 -0
  47. package/dist/cli/commands/maintenance/config.js +145 -0
  48. package/dist/cli/commands/maintenance/doctor.d.ts +2 -0
  49. package/dist/cli/commands/maintenance/doctor.js +52 -0
  50. package/dist/cli/commands/maintenance/host-claude.d.ts +2 -0
  51. package/dist/cli/commands/maintenance/host-claude.js +4 -0
  52. package/dist/cli/commands/maintenance/index.d.ts +8 -0
  53. package/dist/cli/commands/maintenance/index.js +9 -0
  54. package/dist/cli/commands/maintenance/logs.d.ts +2 -0
  55. package/dist/cli/commands/maintenance/logs.js +44 -0
  56. package/dist/cli/commands/maintenance/sync.d.ts +2 -0
  57. package/dist/cli/commands/maintenance/sync.js +12 -0
  58. package/dist/cli/commands/maintenance/watch.d.ts +3 -0
  59. package/dist/cli/commands/maintenance/watch.js +6 -0
  60. package/dist/cli/commands/projects/describe-sessions.d.ts +3 -0
  61. package/dist/cli/commands/projects/describe-sessions.js +15 -0
  62. package/dist/cli/commands/projects/here.d.ts +38 -0
  63. package/dist/cli/commands/projects/here.js +145 -0
  64. package/dist/cli/commands/projects/index.d.ts +4 -0
  65. package/dist/cli/commands/projects/index.js +4 -0
  66. package/dist/cli/commands/projects/projects.d.ts +14 -0
  67. package/dist/cli/commands/projects/projects.js +213 -0
  68. package/dist/cli/commands/projects/restart.d.ts +15 -0
  69. package/dist/cli/commands/projects/restart.js +149 -0
  70. package/dist/cli/commands/registry.d.ts +3 -0
  71. package/dist/cli/commands/registry.js +34 -0
  72. package/dist/cli/commands/repair/checks.js +105 -29
  73. package/dist/cli/commands/repair/finders.d.ts +13 -10
  74. package/dist/cli/commands/repair/finders.js +63 -43
  75. package/dist/cli/commands/repair/index.d.ts +4 -4
  76. package/dist/cli/commands/repair/index.js +47 -21
  77. package/dist/cli/commands/repair/types.d.ts +2 -2
  78. package/dist/cli/commands/repair/types.js +7 -2
  79. package/dist/cli/commands/sessions/attach.d.ts +2 -0
  80. package/dist/cli/commands/sessions/attach.js +45 -0
  81. package/dist/cli/commands/sessions/control.d.ts +4 -0
  82. package/dist/cli/commands/sessions/control.js +62 -0
  83. package/dist/cli/commands/sessions/exec.d.ts +6 -0
  84. package/dist/cli/commands/sessions/exec.js +72 -0
  85. package/dist/cli/commands/sessions/index.d.ts +6 -0
  86. package/dist/cli/commands/sessions/index.js +9 -0
  87. package/dist/cli/commands/sessions/list.d.ts +15 -0
  88. package/dist/cli/commands/sessions/list.js +65 -0
  89. package/dist/cli/commands/sessions/status.d.ts +2 -0
  90. package/dist/cli/commands/sessions/status.js +153 -0
  91. package/dist/cli/commands/sessions/window.d.ts +3 -0
  92. package/dist/cli/commands/sessions/window.js +18 -0
  93. package/dist/cli/commands/setup/checks.d.ts +4 -4
  94. package/dist/cli/commands/setup/checks.js +36 -19
  95. package/dist/cli/commands/setup/facts.d.ts +6 -6
  96. package/dist/cli/commands/setup/facts.js +23 -11
  97. package/dist/cli/commands/setup/index.d.ts +1 -1
  98. package/dist/cli/commands/setup/index.js +25 -12
  99. package/dist/cli/commands/user-config.d.ts +5 -5
  100. package/dist/cli/commands/user-config.js +14 -12
  101. package/dist/cli/history.d.ts +5 -4
  102. package/dist/cli/history.js +23 -11
  103. package/dist/cli/index.d.ts +4 -14
  104. package/dist/cli/index.js +27 -77
  105. package/dist/cli/manifest.d.ts +464 -10
  106. package/dist/cli/manifest.js +328 -54
  107. package/dist/cli/menu/apps.d.ts +7 -5
  108. package/dist/cli/menu/apps.js +64 -16
  109. package/dist/cli/menu/command-fields.d.ts +15 -0
  110. package/dist/cli/menu/command-fields.js +23 -0
  111. package/dist/cli/menu/command-form.d.ts +3 -5
  112. package/dist/cli/menu/command-form.js +116 -48
  113. package/dist/cli/menu/home.d.ts +22 -0
  114. package/dist/cli/menu/home.js +72 -0
  115. package/dist/cli/menu/index.d.ts +2 -24
  116. package/dist/cli/menu/index.js +4 -178
  117. package/dist/cli/menu/menu.d.ts +23 -0
  118. package/dist/cli/menu/menu.js +185 -0
  119. package/dist/cli/menu/settings/categories.d.ts +2 -2
  120. package/dist/cli/menu/settings/categories.js +123 -20
  121. package/dist/cli/menu/settings/collections/collection-editor.d.ts +23 -0
  122. package/dist/cli/menu/settings/collections/collection-editor.js +89 -0
  123. package/dist/cli/menu/settings/collections/map-editor.d.ts +10 -0
  124. package/dist/cli/menu/settings/collections/map-editor.js +34 -0
  125. package/dist/cli/menu/settings/collections/object-list-editor.d.ts +10 -0
  126. package/dist/cli/menu/settings/collections/object-list-editor.js +23 -0
  127. package/dist/cli/menu/settings/collections/object-map-editor.d.ts +10 -0
  128. package/dist/cli/menu/settings/collections/object-map-editor.js +35 -0
  129. package/dist/cli/menu/settings/collections/string-list-editor.d.ts +12 -0
  130. package/dist/cli/menu/settings/collections/string-list-editor.js +39 -0
  131. package/dist/cli/menu/settings/config-file.d.ts +2 -2
  132. package/dist/cli/menu/settings/config-file.js +42 -19
  133. package/dist/cli/menu/settings/editor-actions.d.ts +2 -0
  134. package/dist/cli/menu/settings/editor-actions.js +2 -0
  135. package/dist/cli/menu/settings/format.d.ts +5 -0
  136. package/dist/cli/menu/settings/format.js +39 -0
  137. package/dist/cli/menu/settings/index.d.ts +1 -29
  138. package/dist/cli/menu/settings/index.js +1 -133
  139. package/dist/cli/menu/settings/object-editor.d.ts +12 -0
  140. package/dist/cli/menu/settings/object-editor.js +86 -0
  141. package/dist/cli/menu/settings/schema-node.d.ts +3 -1
  142. package/dist/cli/menu/settings/schema-node.js +71 -24
  143. package/dist/cli/menu/settings/settings-editor.d.ts +30 -0
  144. package/dist/cli/menu/settings/settings-editor.js +176 -0
  145. package/dist/cli/menu/settings/{editors.d.ts → value-editor.d.ts} +2 -13
  146. package/dist/cli/menu/settings/value-editor.js +137 -0
  147. package/dist/cli/menu/several.d.ts +4 -4
  148. package/dist/cli/menu/several.js +61 -20
  149. package/dist/cli/{colors.d.ts → output/colors.d.ts} +8 -8
  150. package/dist/cli/{colors.js → output/colors.js} +32 -14
  151. package/dist/cli/output/index.d.ts +3 -0
  152. package/dist/cli/output/index.js +3 -0
  153. package/dist/cli/output/print.d.ts +5 -0
  154. package/dist/cli/output/print.js +14 -0
  155. package/dist/cli/output/progress.d.ts +24 -0
  156. package/dist/cli/output/progress.js +124 -0
  157. package/dist/cli/report.d.ts +2 -0
  158. package/dist/cli/report.js +20 -0
  159. package/dist/cli/tui/app.d.ts +6 -16
  160. package/dist/cli/tui/app.js +28 -8
  161. package/dist/cli/tui/dialogs/confirm-screen.d.ts +20 -0
  162. package/dist/cli/tui/dialogs/confirm-screen.js +50 -0
  163. package/dist/cli/tui/dialogs/message-screen.d.ts +17 -0
  164. package/dist/cli/tui/dialogs/message-screen.js +55 -0
  165. package/dist/cli/tui/dialogs/paragraphs.d.ts +2 -0
  166. package/dist/cli/tui/dialogs/paragraphs.js +5 -0
  167. package/dist/cli/tui/dialogs/text-screen.d.ts +26 -0
  168. package/dist/cli/tui/dialogs/text-screen.js +107 -0
  169. package/dist/cli/tui/frame.js +3 -1
  170. package/dist/cli/tui/index.d.ts +7 -3
  171. package/dist/cli/tui/index.js +4 -2
  172. package/dist/cli/tui/list/list-screen.d.ts +29 -0
  173. package/dist/cli/tui/{list-screen.js → list/list-screen.js} +86 -23
  174. package/dist/cli/tui/{list-screen.d.ts → list/list-types.d.ts} +0 -28
  175. package/dist/cli/tui/screen.d.ts +14 -0
  176. package/dist/cli/tui/terminal.js +34 -10
  177. package/dist/cli/tui/text.d.ts +2 -1
  178. package/dist/cli/tui/text.js +37 -7
  179. package/dist/cli/tui/theme.js +27 -9
  180. package/dist/cli/validate.d.ts +8 -8
  181. package/dist/cli/validate.js +32 -21
  182. package/dist/core/config/defaults.d.ts +2 -0
  183. package/dist/core/config/defaults.js +203 -0
  184. package/dist/core/config/index.d.ts +2 -0
  185. package/dist/core/config/index.js +3 -0
  186. package/dist/core/{config.d.ts → config/loader.d.ts} +1 -2
  187. package/dist/core/config/loader.js +47 -0
  188. package/dist/core/{detect-databases.js → detect/databases.js} +111 -23
  189. package/dist/core/detect/index.d.ts +4 -0
  190. package/dist/core/detect/index.js +4 -0
  191. package/dist/core/{detect-pwsh.d.ts → detect/pwsh.d.ts} +1 -1
  192. package/dist/core/{detect-pwsh.js → detect/pwsh.js} +25 -11
  193. package/dist/core/{detect-toolchains.d.ts → detect/toolchains.d.ts} +1 -1
  194. package/dist/core/{detect-toolchains.js → detect/toolchains.js} +42 -5
  195. package/dist/{guest/toolchains → core/detect}/versions.js +28 -12
  196. package/dist/core/disk.d.ts +2 -0
  197. package/dist/core/disk.js +46 -3
  198. package/dist/core/local-config/boot-wants.d.ts +45 -0
  199. package/dist/core/local-config/boot-wants.js +120 -0
  200. package/dist/core/local-config/file.d.ts +3 -0
  201. package/dist/core/local-config/file.js +16 -0
  202. package/dist/core/local-config/index.d.ts +5 -0
  203. package/dist/core/local-config/index.js +7 -0
  204. package/dist/core/{local-config.d.ts → local-config/overrides.d.ts} +11 -11
  205. package/dist/core/{local-config.js → local-config/overrides.js} +53 -54
  206. package/dist/core/{project-policy.d.ts → local-config/policy.d.ts} +7 -3
  207. package/dist/core/{project-policy.js → local-config/policy.js} +16 -6
  208. package/dist/core/local-config/trust.d.ts +13 -0
  209. package/dist/core/local-config/trust.js +43 -0
  210. package/dist/core/package-info.d.ts +4 -0
  211. package/dist/core/package-info.js +13 -0
  212. package/dist/core/run/guest-workspace.d.ts +23 -0
  213. package/dist/core/run/guest-workspace.js +47 -0
  214. package/dist/core/run/index.d.ts +3 -0
  215. package/dist/core/run/index.js +3 -0
  216. package/dist/core/run/resolve-run.d.ts +3 -0
  217. package/dist/core/run/resolve-run.js +202 -0
  218. package/dist/core/run/versions.d.ts +13 -0
  219. package/dist/core/run/versions.js +65 -0
  220. package/dist/core/safe-paths.js +17 -5
  221. package/dist/core/schema/apps.d.ts +4 -4
  222. package/dist/core/schema/apps.js +55 -21
  223. package/dist/core/schema/common.d.ts +13 -10
  224. package/dist/core/schema/common.js +16 -10
  225. package/dist/core/schema/config.d.ts +18 -12
  226. package/dist/core/schema/config.js +78 -53
  227. package/dist/core/schema/databases.d.ts +4 -3
  228. package/dist/core/schema/databases.js +16 -12
  229. package/dist/core/schema/harness.d.ts +1 -1
  230. package/dist/core/schema/harness.js +17 -7
  231. package/dist/core/schema/index.d.ts +6 -0
  232. package/dist/core/schema/index.js +8 -0
  233. package/dist/core/schema/json-schema.js +10 -5
  234. package/dist/core/schema/profile.d.ts +4 -4
  235. package/dist/core/schema/profile.js +37 -17
  236. package/dist/core/schema/projects.d.ts +2 -1
  237. package/dist/core/schema/projects.js +16 -5
  238. package/dist/core/schema/sandbox.d.ts +12 -12
  239. package/dist/core/schema/sandbox.js +101 -37
  240. package/dist/core/schema/toolchains.d.ts +6 -1
  241. package/dist/core/schema/toolchains.js +84 -34
  242. package/dist/core/types.d.ts +36 -9
  243. package/dist/core/util/errors.d.ts +8 -0
  244. package/dist/core/util/errors.js +14 -0
  245. package/dist/core/util/fs.d.ts +8 -0
  246. package/dist/core/util/fs.js +40 -0
  247. package/dist/core/util/index.d.ts +7 -0
  248. package/dist/core/util/index.js +7 -0
  249. package/dist/core/util/jsonc.d.ts +6 -0
  250. package/dist/core/util/jsonc.js +25 -0
  251. package/dist/core/util/links.d.ts +10 -0
  252. package/dist/core/util/links.js +39 -0
  253. package/dist/core/util/paths.d.ts +7 -0
  254. package/dist/core/util/paths.js +33 -0
  255. package/dist/core/util/process.d.ts +15 -0
  256. package/dist/core/util/process.js +54 -0
  257. package/dist/core/util/text.d.ts +8 -0
  258. package/dist/core/util/text.js +8 -0
  259. package/dist/guest/{setup/agents.js → agents/agent-installer.js} +24 -4
  260. package/dist/guest/apps/after-install.d.ts +3 -0
  261. package/dist/guest/apps/after-install.js +47 -0
  262. package/dist/guest/apps/app-installer.d.ts +22 -0
  263. package/dist/guest/apps/app-installer.js +116 -0
  264. package/dist/guest/apps/find-exe.d.ts +5 -0
  265. package/dist/guest/apps/find-exe.js +41 -0
  266. package/dist/guest/apps/index.d.ts +3 -10
  267. package/dist/guest/apps/index.js +6 -206
  268. package/dist/guest/apps/resolvers.js +37 -9
  269. package/dist/guest/apps/shortcuts.d.ts +6 -0
  270. package/dist/guest/apps/shortcuts.js +28 -0
  271. package/dist/guest/apps/sources.d.ts +4 -0
  272. package/dist/guest/apps/sources.js +17 -0
  273. package/dist/guest/apps/unpack.d.ts +3 -0
  274. package/dist/guest/apps/unpack.js +47 -0
  275. package/dist/guest/{audit-parse.js → audit/parse.js} +39 -3
  276. package/dist/guest/{audit.d.ts → audit/process-audit.d.ts} +3 -1
  277. package/dist/guest/{audit.js → audit/process-audit.js} +33 -8
  278. package/dist/guest/boot/boot-env.d.ts +4 -0
  279. package/dist/guest/{boot-env.js → boot/boot-env.js} +7 -5
  280. package/dist/guest/boot/boot.d.ts +1 -0
  281. package/dist/guest/{main.js → boot/boot.js} +100 -50
  282. package/dist/guest/{guide.js → boot/guide.js} +32 -7
  283. package/dist/guest/{project-env.d.ts → boot/project-env.d.ts} +3 -3
  284. package/dist/guest/{project-env.js → boot/project-env.js} +12 -4
  285. package/dist/guest/boot/project-status.d.ts +5 -0
  286. package/dist/guest/boot/project-status.js +28 -0
  287. package/dist/guest/daemon/daemon.d.ts +1 -0
  288. package/dist/guest/daemon/daemon.js +51 -0
  289. package/dist/guest/daemon/exec.js +18 -6
  290. package/dist/guest/daemon/{shutdown.js → idle-shutdown.js} +5 -4
  291. package/dist/guest/daemon/{project.d.ts → project-provisioner.d.ts} +3 -3
  292. package/dist/guest/daemon/{project.js → project-provisioner.js} +60 -22
  293. package/dist/guest/daemon/relays.js +5 -3
  294. package/dist/guest/daemon/{session.js → sessions.js} +84 -24
  295. package/dist/guest/daemon/state.d.ts +4 -1
  296. package/dist/guest/daemon/state.js +34 -20
  297. package/dist/guest/databases/database-server.d.ts +13 -0
  298. package/dist/guest/databases/database-server.js +35 -0
  299. package/dist/guest/databases/dynamodb.d.ts +12 -0
  300. package/dist/guest/databases/dynamodb.js +81 -0
  301. package/dist/guest/databases/index.d.ts +2 -0
  302. package/dist/guest/databases/index.js +2 -0
  303. package/dist/guest/databases/mongodb.d.ts +7 -0
  304. package/dist/guest/databases/mongodb.js +46 -0
  305. package/dist/guest/databases/mysql.d.ts +7 -0
  306. package/dist/guest/databases/mysql.js +59 -0
  307. package/dist/guest/databases/names.d.ts +5 -0
  308. package/dist/guest/databases/names.js +8 -0
  309. package/dist/guest/databases/postgres.d.ts +9 -0
  310. package/dist/guest/databases/postgres.js +85 -0
  311. package/dist/guest/databases/redis.d.ts +7 -0
  312. package/dist/guest/databases/redis.js +25 -0
  313. package/dist/guest/databases/registry.d.ts +5 -0
  314. package/dist/guest/databases/registry.js +51 -0
  315. package/dist/guest/databases/sbx-db.d.ts +1 -0
  316. package/dist/guest/{db.js → databases/sbx-db.js} +13 -13
  317. package/dist/guest/{toolchains/databases → databases}/server.d.ts +5 -5
  318. package/dist/guest/{toolchains/databases → databases}/server.js +18 -13
  319. package/dist/guest/entries/daemon.js +16 -0
  320. package/dist/guest/entries/db.js +10 -0
  321. package/dist/guest/entries/gitguard.js +20 -0
  322. package/dist/guest/entries/main.d.ts +1 -0
  323. package/dist/guest/entries/main.js +24 -0
  324. package/dist/guest/entries/netproxy.d.ts +1 -0
  325. package/dist/guest/entries/netproxy.js +7 -0
  326. package/dist/guest/entries/view.d.ts +1 -0
  327. package/dist/guest/entries/view.js +11 -0
  328. package/dist/guest/{gitguard.js → git/decision.js} +49 -26
  329. package/dist/guest/network/addresses.d.ts +2 -0
  330. package/dist/guest/network/addresses.js +6 -0
  331. package/dist/guest/{setup/network.d.ts → network/allow-only.d.ts} +0 -10
  332. package/dist/guest/network/allow-only.js +84 -0
  333. package/dist/guest/network/firewall.d.ts +9 -0
  334. package/dist/guest/{setup/network.js → network/firewall.js} +58 -63
  335. package/dist/guest/network/proxy-server.d.ts +2 -0
  336. package/dist/guest/{netproxy.js → network/proxy-server.js} +37 -18
  337. package/dist/guest/{helpers.d.ts → runtime/csc.d.ts} +1 -1
  338. package/dist/guest/{helpers.js → runtime/csc.js} +7 -2
  339. package/dist/guest/runtime/fs.d.ts +2 -0
  340. package/dist/guest/runtime/fs.js +6 -0
  341. package/dist/guest/runtime/log.d.ts +3 -0
  342. package/dist/guest/runtime/log.js +22 -0
  343. package/dist/guest/runtime/paths.d.ts +13 -0
  344. package/dist/guest/runtime/paths.js +14 -0
  345. package/dist/guest/{ports.js → runtime/ports.js} +8 -2
  346. package/dist/guest/runtime/process.d.ts +15 -0
  347. package/dist/guest/runtime/process.js +59 -0
  348. package/dist/guest/{project-context.js → runtime/project-context.js} +1 -1
  349. package/dist/guest/runtime/session.d.ts +5 -0
  350. package/dist/guest/runtime/session.js +10 -0
  351. package/dist/guest/runtime/status.d.ts +7 -0
  352. package/dist/guest/runtime/status.js +57 -0
  353. package/dist/guest/{cmdline.js → sessions/cmdline.js} +10 -4
  354. package/dist/guest/{ptyhost.js → sessions/pty-host.js} +12 -5
  355. package/dist/guest/{view.js → sessions/viewer.js} +8 -11
  356. package/dist/guest/setup/claude-mem.d.ts +10 -0
  357. package/dist/guest/setup/{claude.js → claude-mem.js} +18 -78
  358. package/dist/guest/setup/{claude.d.ts → claude-profile.d.ts} +0 -10
  359. package/dist/guest/setup/claude-profile.js +89 -0
  360. package/dist/guest/setup/desktop.d.ts +2 -0
  361. package/dist/guest/setup/desktop.js +32 -0
  362. package/dist/guest/setup/environment.js +28 -5
  363. package/dist/guest/setup/{user.d.ts → git-identity.d.ts} +0 -2
  364. package/dist/guest/setup/git-identity.js +34 -0
  365. package/dist/guest/{gitrules.d.ts → setup/git-rules.d.ts} +1 -1
  366. package/dist/guest/setup/git-rules.js +50 -0
  367. package/dist/guest/setup/hooks.js +22 -5
  368. package/dist/guest/setup/{policy.js → managed-policy.js} +2 -2
  369. package/dist/guest/toolchains/catalogue.d.ts +4 -4
  370. package/dist/guest/toolchains/catalogue.js +30 -7
  371. package/dist/guest/toolchains/detect.d.ts +12 -0
  372. package/dist/guest/toolchains/detect.js +54 -0
  373. package/dist/guest/toolchains/index.d.ts +3 -17
  374. package/dist/guest/toolchains/index.js +1 -80
  375. package/dist/guest/toolchains/install.d.ts +20 -0
  376. package/dist/guest/toolchains/install.js +29 -0
  377. package/dist/guest/toolchains/languages/go.d.ts +3 -0
  378. package/dist/guest/toolchains/{go.js → languages/go.js} +27 -9
  379. package/dist/guest/toolchains/languages/java.d.ts +8 -0
  380. package/dist/guest/toolchains/{java.js → languages/java.js} +57 -18
  381. package/dist/guest/toolchains/languages/node.d.ts +3 -0
  382. package/dist/guest/toolchains/{node.js → languages/node.js} +51 -18
  383. package/dist/guest/toolchains/languages/php.d.ts +3 -0
  384. package/dist/guest/toolchains/{scripting → languages}/php.js +36 -11
  385. package/dist/guest/toolchains/languages/python-tools.d.ts +3 -0
  386. package/dist/guest/toolchains/languages/python-tools.js +12 -0
  387. package/dist/guest/toolchains/languages/python.d.ts +3 -0
  388. package/dist/guest/toolchains/{python.js → languages/python.js} +29 -16
  389. package/dist/guest/toolchains/languages/ruby.d.ts +3 -0
  390. package/dist/guest/toolchains/{scripting → languages}/ruby.js +28 -10
  391. package/dist/guest/toolchains/leftovers.d.ts +1 -1
  392. package/dist/guest/toolchains/leftovers.js +13 -11
  393. package/dist/guest/toolchains/managers.d.ts +6 -6
  394. package/dist/guest/toolchains/managers.js +38 -17
  395. package/dist/guest/toolchains/native/binstall.d.ts +3 -2
  396. package/dist/guest/toolchains/native/binstall.js +20 -8
  397. package/dist/guest/toolchains/native/cpp.d.ts +2 -2
  398. package/dist/guest/toolchains/native/cpp.js +23 -8
  399. package/dist/guest/toolchains/native/dotnet.d.ts +5 -3
  400. package/dist/guest/toolchains/native/dotnet.js +72 -24
  401. package/dist/guest/toolchains/native/mesa.d.ts +2 -2
  402. package/dist/guest/toolchains/native/mesa.js +27 -10
  403. package/dist/guest/toolchains/native/msvc/environment.d.ts +4 -4
  404. package/dist/guest/toolchains/native/msvc/environment.js +30 -16
  405. package/dist/guest/toolchains/native/msvc/index.d.ts +3 -3
  406. package/dist/guest/toolchains/native/msvc/index.js +10 -8
  407. package/dist/guest/toolchains/native/msvc/packages.d.ts +1 -1
  408. package/dist/guest/toolchains/native/msvc/packages.js +69 -23
  409. package/dist/guest/toolchains/native/msvc/tree.d.ts +6 -6
  410. package/dist/guest/toolchains/native/msvc/tree.js +15 -9
  411. package/dist/guest/toolchains/native/rust-extras.d.ts +23 -0
  412. package/dist/guest/toolchains/native/rust-extras.js +100 -0
  413. package/dist/guest/toolchains/native/rust.d.ts +2 -2
  414. package/dist/guest/toolchains/native/rust.js +41 -10
  415. package/dist/guest/toolchains/{scripting → native}/vcruntime.d.ts +2 -2
  416. package/dist/guest/toolchains/{scripting → native}/vcruntime.js +17 -7
  417. package/dist/guest/toolchains/package-ledger.d.ts +17 -0
  418. package/dist/guest/toolchains/package-ledger.js +54 -0
  419. package/dist/guest/toolchains/plan.d.ts +3 -24
  420. package/dist/guest/toolchains/plan.js +99 -111
  421. package/dist/guest/toolchains/runtimes.d.ts +6 -6
  422. package/dist/guest/toolchains/runtimes.js +31 -13
  423. package/dist/guest/toolchains/scheduler.d.ts +22 -0
  424. package/dist/guest/toolchains/scheduler.js +123 -0
  425. package/dist/guest/toolchains/setup.d.ts +10 -0
  426. package/dist/guest/toolchains/setup.js +22 -0
  427. package/dist/guest/toolchains/state-file.d.ts +3 -0
  428. package/dist/guest/toolchains/state-file.js +10 -0
  429. package/dist/guest/toolchains/step.d.ts +24 -0
  430. package/dist/guest/toolchains/step.js +1 -0
  431. package/dist/guest/toolchains/tool-env.d.ts +12 -0
  432. package/dist/guest/toolchains/tool-env.js +16 -0
  433. package/dist/guest/toolchains/tools/cli.d.ts +10 -0
  434. package/dist/guest/toolchains/{cli.js → tools/cli.js} +35 -15
  435. package/dist/guest/toolchains/tools/git.d.ts +3 -0
  436. package/dist/guest/toolchains/{git.js → tools/git.js} +38 -15
  437. package/dist/guest/toolchains/tools/pwsh.d.ts +4 -0
  438. package/dist/guest/toolchains/{pwsh.js → tools/pwsh.js} +14 -7
  439. package/dist/guest/toolchains/{vscode-profile.d.ts → tools/vscode-profile.d.ts} +6 -6
  440. package/dist/guest/toolchains/{vscode-profile.js → tools/vscode-profile.js} +28 -12
  441. package/dist/guest/toolchains/{vscode.d.ts → tools/vscode.d.ts} +6 -6
  442. package/dist/guest/toolchains/{vscode.js → tools/vscode.js} +67 -21
  443. package/dist/guest/toolchains/version-cache.d.ts +16 -0
  444. package/dist/guest/toolchains/version-cache.js +67 -0
  445. package/dist/host/agent-commands/commands.d.ts +13 -0
  446. package/dist/host/agent-commands/commands.js +33 -0
  447. package/dist/host/agent-commands/forwarders.d.ts +7 -0
  448. package/dist/host/agent-commands/forwarders.js +31 -0
  449. package/dist/host/agent-commands/index.d.ts +4 -0
  450. package/dist/host/agent-commands/index.js +4 -0
  451. package/dist/host/agent-commands/reconcile.d.ts +12 -0
  452. package/dist/host/agent-commands/reconcile.js +69 -0
  453. package/dist/host/agent-commands/user-path.d.ts +2 -0
  454. package/dist/host/agent-commands/user-path.js +33 -0
  455. package/dist/host/audit/collect.d.ts +2 -2
  456. package/dist/host/audit/collect.js +59 -22
  457. package/dist/host/audit/log.d.ts +2 -2
  458. package/dist/host/audit/log.js +24 -8
  459. package/dist/host/{attach.d.ts → channel/attach.d.ts} +2 -2
  460. package/dist/host/{attach.js → channel/attach.js} +33 -15
  461. package/dist/host/channel/channel.d.ts +51 -0
  462. package/dist/host/channel/channel.js +196 -0
  463. package/dist/host/channel/index.d.ts +2 -0
  464. package/dist/host/channel/index.js +2 -0
  465. package/dist/host/guard/agent-files.d.ts +7 -0
  466. package/dist/host/guard/agent-files.js +103 -0
  467. package/dist/host/guard/commands.d.ts +10 -0
  468. package/dist/host/guard/commands.js +123 -0
  469. package/dist/host/guard/file-hash.d.ts +4 -0
  470. package/dist/host/guard/file-hash.js +37 -0
  471. package/dist/host/guard/git-config.d.ts +5 -0
  472. package/dist/host/guard/git-config.js +62 -0
  473. package/dist/host/guard/git-dirs.d.ts +12 -0
  474. package/dist/host/guard/git-dirs.js +53 -0
  475. package/dist/host/guard/index.d.ts +5 -0
  476. package/dist/host/guard/index.js +4 -0
  477. package/dist/host/guard/mark-of-the-web.d.ts +8 -0
  478. package/dist/host/guard/mark-of-the-web.js +74 -0
  479. package/dist/host/guard/nested-repos.d.ts +14 -0
  480. package/dist/host/guard/nested-repos.js +88 -0
  481. package/dist/host/guard/quarantine.d.ts +3 -0
  482. package/dist/host/guard/quarantine.js +24 -0
  483. package/dist/host/guard/repo-guard.d.ts +10 -0
  484. package/dist/host/guard/repo-guard.js +36 -0
  485. package/dist/host/guard/store.d.ts +40 -0
  486. package/dist/host/guard/store.js +145 -0
  487. package/dist/host/guard/types.d.ts +27 -0
  488. package/dist/host/guard/types.js +3 -0
  489. package/dist/host/guard/watch-state.d.ts +9 -0
  490. package/dist/host/guard/watch-state.js +26 -0
  491. package/dist/host/launch/boot-projects.d.ts +17 -0
  492. package/dist/host/launch/{projects.js → boot-projects.js} +27 -12
  493. package/dist/host/{database-plan.d.ts → launch/database-plan.d.ts} +5 -5
  494. package/dist/host/{database-plan.js → launch/database-plan.js} +24 -13
  495. package/dist/host/launch/generate.d.ts +4 -0
  496. package/dist/host/launch/generate.js +77 -0
  497. package/dist/host/launch/index.d.ts +10 -0
  498. package/dist/host/launch/index.js +10 -0
  499. package/dist/host/launch/mappings.d.ts +7 -2
  500. package/dist/host/launch/mappings.js +83 -24
  501. package/dist/host/launch/pc-scan.d.ts +5 -0
  502. package/dist/host/{pc-scan.js → launch/pc-scan.js} +20 -13
  503. package/dist/host/launch/project-scan.d.ts +7 -0
  504. package/dist/host/{project-scan.js → launch/project-scan.js} +29 -21
  505. package/dist/host/launch/session-file.d.ts +23 -0
  506. package/dist/host/launch/session-file.js +73 -0
  507. package/dist/host/launch/stage.d.ts +5 -5
  508. package/dist/host/launch/stage.js +14 -13
  509. package/dist/host/launch/toolchains.d.ts +4 -0
  510. package/dist/host/launch/toolchains.js +11 -0
  511. package/dist/host/launch/{wsb.d.ts → wsb-file.d.ts} +4 -2
  512. package/dist/host/launch/wsb-file.js +56 -0
  513. package/dist/host/life/crash-report.d.ts +8 -0
  514. package/dist/host/life/crash-report.js +87 -0
  515. package/dist/host/life/index.d.ts +6 -0
  516. package/dist/host/life/index.js +6 -0
  517. package/dist/host/life/keep-awake.d.ts +10 -0
  518. package/dist/host/life/keep-awake.js +29 -0
  519. package/dist/host/life/life-record.d.ts +48 -0
  520. package/dist/host/life/life-record.js +76 -0
  521. package/dist/host/life/stop-events.d.ts +27 -0
  522. package/dist/host/life/stop-events.js +96 -0
  523. package/dist/host/life/stop-warning.d.ts +4 -0
  524. package/dist/host/life/stop-warning.js +25 -0
  525. package/dist/host/life/windows-update.d.ts +3 -0
  526. package/dist/host/life/windows-update.js +11 -0
  527. package/dist/host/native.d.ts +4 -0
  528. package/dist/host/native.js +11 -0
  529. package/dist/host/network/index.d.ts +1 -0
  530. package/dist/host/network/index.js +1 -0
  531. package/dist/host/{port-forward.d.ts → network/port-forward.d.ts} +1 -1
  532. package/dist/host/{port-forward.js → network/port-forward.js} +16 -10
  533. package/dist/host/profile/accounts.d.ts +37 -0
  534. package/dist/host/profile/accounts.js +146 -0
  535. package/dist/host/profile/claude-login.d.ts +22 -0
  536. package/dist/host/profile/claude-login.js +57 -0
  537. package/dist/host/{claude-profile.d.ts → profile/claude-profile.d.ts} +9 -9
  538. package/dist/host/{claude-profile.js → profile/claude-profile.js} +32 -22
  539. package/dist/host/profile/index.d.ts +7 -0
  540. package/dist/host/profile/index.js +7 -0
  541. package/dist/host/profile/personalize.d.ts +2 -0
  542. package/dist/host/profile/personalize.js +127 -0
  543. package/dist/host/profile/reg-file.d.ts +8 -0
  544. package/dist/host/profile/reg-file.js +45 -0
  545. package/dist/host/profile/secret-files.d.ts +2 -0
  546. package/dist/host/profile/secret-files.js +25 -0
  547. package/dist/host/profile/secret-patterns.d.ts +6 -0
  548. package/dist/host/profile/secret-patterns.js +128 -0
  549. package/dist/host/profile/secrets.d.ts +12 -0
  550. package/dist/host/profile/secrets.js +100 -0
  551. package/dist/host/projects/index.d.ts +4 -0
  552. package/dist/host/projects/index.js +4 -0
  553. package/dist/host/projects/join.d.ts +38 -0
  554. package/dist/host/projects/join.js +119 -0
  555. package/dist/host/projects/known.d.ts +28 -0
  556. package/dist/host/projects/known.js +55 -0
  557. package/dist/host/projects/mapper.d.ts +29 -0
  558. package/dist/host/projects/mapper.js +88 -0
  559. package/dist/host/projects/registry.d.ts +83 -0
  560. package/dist/host/projects/registry.js +136 -0
  561. package/dist/host/sandbox/doctor.d.ts +2 -0
  562. package/dist/host/sandbox/doctor.js +42 -0
  563. package/dist/host/sandbox/host-claude.d.ts +1 -0
  564. package/dist/host/sandbox/host-claude.js +26 -0
  565. package/dist/host/sandbox/index.d.ts +6 -0
  566. package/dist/host/sandbox/index.js +6 -0
  567. package/dist/host/{platform.d.ts → sandbox/platform.d.ts} +0 -5
  568. package/dist/host/sandbox/platform.js +60 -0
  569. package/dist/host/sandbox/probe.d.ts +3 -0
  570. package/dist/host/sandbox/probe.js +47 -0
  571. package/dist/host/{window.js → sandbox/window.js} +7 -5
  572. package/dist/host/{wsb.js → sandbox/wsb-cli.js} +31 -8
  573. package/dist/host/{cleanup.js → storage/cleanup.js} +27 -12
  574. package/dist/host/storage/index.d.ts +2 -0
  575. package/dist/host/storage/index.js +2 -0
  576. package/dist/host/storage/state-files.d.ts +4 -0
  577. package/dist/host/storage/state-files.js +10 -0
  578. package/dist/host/test-guard.js +1 -1
  579. package/dist/host/tools/conpty.d.ts +8 -0
  580. package/dist/host/tools/conpty.js +58 -0
  581. package/dist/host/tools/index.d.ts +2 -0
  582. package/dist/host/tools/index.js +2 -0
  583. package/dist/host/{terminal.d.ts → tools/windows-terminal.d.ts} +2 -10
  584. package/dist/host/{terminal.js → tools/windows-terminal.js} +33 -57
  585. package/dist/host/workspace-view/active-views.d.ts +3 -0
  586. package/dist/host/workspace-view/active-views.js +22 -0
  587. package/dist/host/workspace-view/index.d.ts +2 -18
  588. package/dist/host/workspace-view/index.js +2 -49
  589. package/dist/host/workspace-view/plan.d.ts +16 -0
  590. package/dist/host/workspace-view/plan.js +50 -0
  591. package/dist/host/workspace-view/rules.js +10 -3
  592. package/dist/host/workspace-view/view-state.d.ts +10 -0
  593. package/dist/host/workspace-view/view-state.js +31 -0
  594. package/dist/host/workspace-view/view.d.ts +1 -0
  595. package/dist/host/workspace-view/view.js +51 -55
  596. package/dist/runtime/daemon.js +4232 -1918
  597. package/dist/runtime/db.js +2145 -830
  598. package/dist/runtime/gitguard.js +29 -11
  599. package/dist/runtime/main.js +4760 -2155
  600. package/dist/runtime/netproxy.js +1654 -418
  601. package/dist/runtime/view.js +1515 -453
  602. package/dist/selftest/accounts.test.d.ts +1 -1
  603. package/dist/selftest/accounts.test.js +20 -17
  604. package/dist/selftest/agent-commands.test.d.ts +1 -1
  605. package/dist/selftest/agent-commands.test.js +9 -5
  606. package/dist/selftest/audit.test.d.ts +1 -1
  607. package/dist/selftest/audit.test.js +46 -13
  608. package/dist/selftest/channel.test.d.ts +1 -1
  609. package/dist/selftest/channel.test.js +91 -8
  610. package/dist/selftest/cli.test.d.ts +1 -1
  611. package/dist/selftest/cli.test.js +68 -16
  612. package/dist/selftest/cmdline.test.d.ts +1 -1
  613. package/dist/selftest/cmdline.test.js +36 -7
  614. package/dist/selftest/config.test.d.ts +1 -1
  615. package/dist/selftest/config.test.js +12 -5
  616. package/dist/selftest/data.test.d.ts +1 -1
  617. package/dist/selftest/data.test.js +35 -6
  618. package/dist/selftest/detect.test.d.ts +1 -1
  619. package/dist/selftest/detect.test.js +22 -9
  620. package/dist/selftest/generate.test.d.ts +1 -1
  621. package/dist/selftest/generate.test.js +33 -9
  622. package/dist/selftest/git-access.test.d.ts +1 -1
  623. package/dist/selftest/git-access.test.js +42 -4
  624. package/dist/selftest/guest-boot.test.d.ts +1 -1
  625. package/dist/selftest/guest-boot.test.js +25 -7
  626. package/dist/selftest/host-sim.test.d.ts +1 -1
  627. package/dist/selftest/host-sim.test.js +27 -3
  628. package/dist/selftest/hostile-input.test.d.ts +1 -1
  629. package/dist/selftest/hostile-input.test.js +5 -5
  630. package/dist/selftest/index.d.ts +1 -1
  631. package/dist/selftest/index.js +73 -16
  632. package/dist/selftest/layout.test.d.ts +2 -0
  633. package/dist/selftest/layout.test.js +131 -0
  634. package/dist/selftest/links.test.d.ts +1 -1
  635. package/dist/selftest/links.test.js +16 -11
  636. package/dist/selftest/live-daemon.test.d.ts +1 -1
  637. package/dist/selftest/live-daemon.test.js +20 -8
  638. package/dist/selftest/live-git.test.d.ts +1 -1
  639. package/dist/selftest/live-git.test.js +13 -4
  640. package/dist/selftest/live-network.test.d.ts +1 -1
  641. package/dist/selftest/live-network.test.js +24 -9
  642. package/dist/selftest/live-projects.test.d.ts +1 -1
  643. package/dist/selftest/live-projects.test.js +47 -20
  644. package/dist/selftest/live-terminal.test.d.ts +2 -0
  645. package/dist/selftest/live-terminal.test.js +195 -0
  646. package/dist/selftest/local-config.test.d.ts +1 -1
  647. package/dist/selftest/local-config.test.js +88 -15
  648. package/dist/selftest/mirror.test.d.ts +1 -1
  649. package/dist/selftest/mirror.test.js +118 -19
  650. package/dist/selftest/network.test.d.ts +1 -1
  651. package/dist/selftest/network.test.js +17 -8
  652. package/dist/selftest/personalization.test.d.ts +1 -1
  653. package/dist/selftest/personalization.test.js +12 -5
  654. package/dist/selftest/projects.test.d.ts +1 -1
  655. package/dist/selftest/projects.test.js +336 -72
  656. package/dist/selftest/repair.test.d.ts +1 -1
  657. package/dist/selftest/repair.test.js +17 -5
  658. package/dist/selftest/repo-guard.test.d.ts +1 -1
  659. package/dist/selftest/repo-guard.test.js +21 -20
  660. package/dist/selftest/secrets.test.d.ts +1 -1
  661. package/dist/selftest/secrets.test.js +57 -13
  662. package/dist/selftest/setup.test.d.ts +1 -1
  663. package/dist/selftest/setup.test.js +25 -5
  664. package/dist/selftest/{fixtures.d.ts → support/fixtures.d.ts} +7 -4
  665. package/dist/selftest/{fixtures.js → support/fixtures.js} +95 -17
  666. package/dist/selftest/{harness.js → support/harness.js} +24 -7
  667. package/dist/selftest/{live.d.ts → support/live.d.ts} +2 -2
  668. package/dist/selftest/{live.js → support/live.js} +34 -10
  669. package/dist/selftest/support/suite.js +1 -0
  670. package/dist/selftest/sync.test.d.ts +1 -1
  671. package/dist/selftest/sync.test.js +64 -26
  672. package/dist/selftest/test-guard.test.d.ts +1 -1
  673. package/dist/selftest/test-guard.test.js +43 -15
  674. package/dist/selftest/toolchains.test.d.ts +1 -1
  675. package/dist/selftest/toolchains.test.js +135 -36
  676. package/dist/selftest/workspace-view.test.d.ts +1 -1
  677. package/dist/selftest/workspace-view.test.js +48 -11
  678. package/dist/selftest/workspace.test.d.ts +1 -1
  679. package/dist/selftest/workspace.test.js +13 -4
  680. package/dist/shared/{apps.d.ts → apps/catalogue.d.ts} +1 -11
  681. package/dist/shared/apps/catalogue.js +768 -0
  682. package/dist/shared/apps/index.d.ts +2 -0
  683. package/dist/shared/apps/index.js +2 -0
  684. package/dist/shared/apps/selection.d.ts +11 -0
  685. package/dist/shared/apps/selection.js +40 -0
  686. package/dist/shared/channel/index.d.ts +2 -0
  687. package/dist/shared/channel/index.js +2 -0
  688. package/dist/shared/channel/run-dir.d.ts +30 -0
  689. package/dist/shared/channel/run-dir.js +84 -0
  690. package/dist/shared/{schema.d.ts → channel/schema.d.ts} +60 -19
  691. package/dist/shared/channel/schema.js +131 -0
  692. package/dist/shared/download/archive.d.ts +13 -0
  693. package/dist/shared/download/archive.js +57 -0
  694. package/dist/shared/download/downloader.d.ts +35 -0
  695. package/dist/shared/download/downloader.js +110 -0
  696. package/dist/shared/download/github.d.ts +16 -0
  697. package/dist/shared/download/github.js +74 -0
  698. package/dist/shared/download/http.d.ts +5 -0
  699. package/dist/shared/download/http.js +30 -0
  700. package/dist/shared/download/index.d.ts +5 -0
  701. package/dist/shared/download/index.js +5 -0
  702. package/dist/shared/download/spawn.d.ts +2 -0
  703. package/dist/shared/download/spawn.js +7 -0
  704. package/dist/shared/io/index.d.ts +3 -0
  705. package/dist/shared/io/index.js +3 -0
  706. package/dist/shared/io/json-file.d.ts +10 -0
  707. package/dist/shared/io/json-file.js +21 -0
  708. package/dist/shared/io/json.d.ts +13 -0
  709. package/dist/shared/io/json.js +49 -0
  710. package/dist/shared/{safe-remove.js → io/safe-remove.js} +32 -7
  711. package/dist/shared/{netrules.js → network/firewall-rules.js} +36 -5
  712. package/dist/shared/network/index.d.ts +2 -0
  713. package/dist/shared/network/index.js +2 -0
  714. package/dist/shared/{netpolicy.js → network/policy.js} +66 -11
  715. package/dist/shared/{paths.js → paths/claude-paths.js} +12 -2
  716. package/dist/shared/{guest-paths.d.ts → paths/guest-paths.d.ts} +21 -0
  717. package/dist/shared/paths/guest-paths.js +146 -0
  718. package/dist/shared/paths/index.d.ts +3 -0
  719. package/dist/shared/paths/index.js +3 -0
  720. package/dist/shared/{projects.d.ts → paths/projects.d.ts} +27 -4
  721. package/dist/shared/paths/projects.js +136 -0
  722. package/dist/shared/pty/client.d.ts +21 -0
  723. package/dist/shared/pty/client.js +79 -0
  724. package/dist/shared/pty/console-input.d.ts +11 -0
  725. package/dist/shared/pty/console-input.js +81 -0
  726. package/dist/shared/pty/index.d.ts +6 -0
  727. package/dist/shared/pty/index.js +6 -0
  728. package/dist/shared/pty/input-joiner.d.ts +15 -0
  729. package/dist/shared/pty/input-joiner.js +44 -0
  730. package/dist/shared/pty/output-filter.d.ts +13 -0
  731. package/dist/shared/pty/output-filter.js +140 -0
  732. package/dist/shared/pty/protocol.d.ts +36 -0
  733. package/dist/shared/pty/protocol.js +60 -0
  734. package/dist/shared/pty/terminal.d.ts +24 -0
  735. package/dist/shared/pty/terminal.js +147 -0
  736. package/dist/shared/test-guard.js +3 -1
  737. package/dist/sync/claude-mem.d.ts +1 -1
  738. package/dist/sync/claude-mem.js +9 -4
  739. package/dist/sync/history.d.ts +1 -29
  740. package/dist/sync/history.js +57 -45
  741. package/dist/sync/index.d.ts +5 -0
  742. package/dist/sync/index.js +5 -0
  743. package/dist/sync/sync-cycle.d.ts +18 -0
  744. package/dist/sync/sync-cycle.js +85 -0
  745. package/dist/sync/sync-state.d.ts +32 -0
  746. package/dist/sync/sync-state.js +37 -0
  747. package/dist/sync/watcher.d.ts +0 -18
  748. package/dist/sync/watcher.js +66 -100
  749. package/native/keep-awake.ps1 +8 -0
  750. package/native/power.cs +23 -0
  751. package/native/stop-events.ps1 +38 -0
  752. package/package.json +11 -3
  753. package/sandbox/linkgate.cs +98 -0
  754. package/sandbox/memlog.ps1 +15 -6
  755. package/sandbox/ptyhost.cs +60 -3
  756. package/schemas/config.schema.json +48 -1
  757. package/schemas/sandbox-config.schema.json +37 -3
  758. package/dist/cli/commands/launch.d.ts +0 -29
  759. package/dist/cli/commands/launch.js +0 -366
  760. package/dist/cli/commands/maintenance.d.ts +0 -10
  761. package/dist/cli/commands/maintenance.js +0 -187
  762. package/dist/cli/commands/project.d.ts +0 -29
  763. package/dist/cli/commands/project.js +0 -63
  764. package/dist/cli/commands/projects.d.ts +0 -14
  765. package/dist/cli/commands/projects.js +0 -146
  766. package/dist/cli/commands/restart.d.ts +0 -6
  767. package/dist/cli/commands/restart.js +0 -85
  768. package/dist/cli/commands/sessions.d.ts +0 -12
  769. package/dist/cli/commands/sessions.js +0 -257
  770. package/dist/cli/menu/settings/editors.js +0 -305
  771. package/dist/cli/progress.d.ts +0 -9
  772. package/dist/cli/progress.js +0 -49
  773. package/dist/cli/tui/dialogs.d.ts +0 -57
  774. package/dist/cli/tui/dialogs.js +0 -162
  775. package/dist/core/config.js +0 -109
  776. package/dist/core/schema.d.ts +0 -6
  777. package/dist/core/schema.js +0 -8
  778. package/dist/core/util.d.ts +0 -62
  779. package/dist/core/util.js +0 -156
  780. package/dist/core/workspace.d.ts +0 -18
  781. package/dist/core/workspace.js +0 -145
  782. package/dist/guest/boot-env.d.ts +0 -4
  783. package/dist/guest/daemon.js +0 -57
  784. package/dist/guest/env.d.ts +0 -52
  785. package/dist/guest/env.js +0 -103
  786. package/dist/guest/gitrules.js +0 -11
  787. package/dist/guest/project-status.d.ts +0 -5
  788. package/dist/guest/project-status.js +0 -17
  789. package/dist/guest/setup/user.js +0 -51
  790. package/dist/guest/toolchains/cli.d.ts +0 -10
  791. package/dist/guest/toolchains/common.d.ts +0 -54
  792. package/dist/guest/toolchains/common.js +0 -147
  793. package/dist/guest/toolchains/databases/dynamodb.d.ts +0 -8
  794. package/dist/guest/toolchains/databases/dynamodb.js +0 -52
  795. package/dist/guest/toolchains/databases/index.d.ts +0 -6
  796. package/dist/guest/toolchains/databases/index.js +0 -62
  797. package/dist/guest/toolchains/databases/mongodb.d.ts +0 -3
  798. package/dist/guest/toolchains/databases/mongodb.js +0 -31
  799. package/dist/guest/toolchains/databases/mysql.d.ts +0 -3
  800. package/dist/guest/toolchains/databases/mysql.js +0 -38
  801. package/dist/guest/toolchains/databases/postgres.d.ts +0 -5
  802. package/dist/guest/toolchains/databases/postgres.js +0 -38
  803. package/dist/guest/toolchains/databases/redis.d.ts +0 -3
  804. package/dist/guest/toolchains/databases/redis.js +0 -16
  805. package/dist/guest/toolchains/git.d.ts +0 -3
  806. package/dist/guest/toolchains/go.d.ts +0 -3
  807. package/dist/guest/toolchains/java.d.ts +0 -8
  808. package/dist/guest/toolchains/node.d.ts +0 -3
  809. package/dist/guest/toolchains/pwsh.d.ts +0 -4
  810. package/dist/guest/toolchains/python.d.ts +0 -3
  811. package/dist/guest/toolchains/scripting/php.d.ts +0 -3
  812. package/dist/guest/toolchains/scripting/ruby.d.ts +0 -3
  813. package/dist/host/accounts.d.ts +0 -32
  814. package/dist/host/accounts.js +0 -128
  815. package/dist/host/agent-commands.d.ts +0 -25
  816. package/dist/host/agent-commands.js +0 -145
  817. package/dist/host/channel.d.ts +0 -38
  818. package/dist/host/channel.js +0 -162
  819. package/dist/host/generate.d.ts +0 -13
  820. package/dist/host/generate.js +0 -108
  821. package/dist/host/join.d.ts +0 -28
  822. package/dist/host/join.js +0 -76
  823. package/dist/host/launch/projects.d.ts +0 -15
  824. package/dist/host/launch/wsb.js +0 -34
  825. package/dist/host/motw.d.ts +0 -17
  826. package/dist/host/motw.js +0 -74
  827. package/dist/host/pc-scan.d.ts +0 -6
  828. package/dist/host/personalize.d.ts +0 -10
  829. package/dist/host/personalize.js +0 -97
  830. package/dist/host/platform.js +0 -129
  831. package/dist/host/project-scan.d.ts +0 -7
  832. package/dist/host/projects.d.ts +0 -100
  833. package/dist/host/projects.js +0 -147
  834. package/dist/host/repo-guard.d.ts +0 -43
  835. package/dist/host/repo-guard.js +0 -347
  836. package/dist/host/secrets.d.ts +0 -14
  837. package/dist/host/secrets.js +0 -133
  838. package/dist/host/stops.d.ts +0 -67
  839. package/dist/host/stops.js +0 -126
  840. package/dist/shared/apps.js +0 -114
  841. package/dist/shared/download.d.ts +0 -60
  842. package/dist/shared/download.js +0 -215
  843. package/dist/shared/guest-paths.js +0 -61
  844. package/dist/shared/projects.js +0 -67
  845. package/dist/shared/pty-client.d.ts +0 -91
  846. package/dist/shared/pty-client.js +0 -349
  847. package/dist/shared/rundir.d.ts +0 -41
  848. package/dist/shared/rundir.js +0 -96
  849. package/dist/shared/schema.js +0 -92
  850. /package/dist/{guest/daemon.d.ts → cli/tui/list/list-types.js} +0 -0
  851. /package/dist/{guest/db.d.ts → cli/tui/screen.js} +0 -0
  852. /package/dist/core/{detect-databases.d.ts → detect/databases.d.ts} +0 -0
  853. /package/dist/{guest/toolchains → core/detect}/versions.d.ts +0 -0
  854. /package/dist/guest/{setup/agents.d.ts → agents/agent-installer.d.ts} +0 -0
  855. /package/dist/guest/{audit-parse.d.ts → audit/parse.d.ts} +0 -0
  856. /package/dist/guest/{guide.d.ts → boot/guide.d.ts} +0 -0
  857. /package/dist/guest/daemon/{shutdown.d.ts → idle-shutdown.d.ts} +0 -0
  858. /package/dist/guest/daemon/{session.d.ts → sessions.d.ts} +0 -0
  859. /package/dist/guest/{main.d.ts → entries/daemon.d.ts} +0 -0
  860. /package/dist/guest/{netproxy.d.ts → entries/db.d.ts} +0 -0
  861. /package/dist/{selftest/suite.js → guest/entries/gitguard.d.ts} +0 -0
  862. /package/dist/guest/{gitguard.d.ts → git/decision.d.ts} +0 -0
  863. /package/dist/guest/{ports.d.ts → runtime/ports.d.ts} +0 -0
  864. /package/dist/guest/{project-context.d.ts → runtime/project-context.d.ts} +0 -0
  865. /package/dist/guest/{cmdline.d.ts → sessions/cmdline.d.ts} +0 -0
  866. /package/dist/guest/{ptyhost.d.ts → sessions/pty-host.d.ts} +0 -0
  867. /package/dist/guest/{view.d.ts → sessions/viewer.d.ts} +0 -0
  868. /package/dist/guest/setup/{policy.d.ts → managed-policy.d.ts} +0 -0
  869. /package/dist/host/{window.d.ts → sandbox/window.d.ts} +0 -0
  870. /package/dist/host/{wsb.d.ts → sandbox/wsb-cli.d.ts} +0 -0
  871. /package/dist/host/{cleanup.d.ts → storage/cleanup.d.ts} +0 -0
  872. /package/dist/selftest/{harness.d.ts → support/harness.d.ts} +0 -0
  873. /package/dist/selftest/{suite.d.ts → support/suite.d.ts} +0 -0
  874. /package/dist/shared/{safe-remove.d.ts → io/safe-remove.d.ts} +0 -0
  875. /package/dist/shared/{netrules.d.ts → network/firewall-rules.d.ts} +0 -0
  876. /package/dist/shared/{netpolicy.d.ts → network/policy.d.ts} +0 -0
  877. /package/dist/shared/{paths.d.ts → paths/claude-paths.d.ts} +0 -0
@@ -6,9 +6,9 @@
6
6
  import fs from 'node:fs';
7
7
  import path from 'node:path';
8
8
  import { spawn } from 'node:child_process';
9
- import { ensureDir, sleep } from '../core/util.js';
10
- import { connect, encodeFrame, FrameReader, FrameType, helloFrame, queryViewers } from '../shared/pty-client.js';
11
- import { readJsonFile, writeJsonAtomic } from '../shared/rundir.js';
9
+ import { ensureDir, sleep } from '../../core/util/index.js';
10
+ import { connect, encodeFrame, FrameReader, FrameType, helloFrame, queryViewers, } from '../../shared/pty/index.js';
11
+ import { readJsonFile, writeJsonAtomic } from '../../shared/io/index.js';
12
12
  const WINDIR = process.env.WINDIR ?? 'C:\\Windows';
13
13
  export const CSC = path.join(WINDIR, 'Microsoft.NET', 'Framework64', 'v4.0.30319', 'csc.exe');
14
14
  /** Live suites need Windows (ConPTY) and the .NET Framework compiler that ships with it. */
@@ -49,7 +49,9 @@ export const openViewer = async (attach, options = {}) => {
49
49
  }
50
50
  });
51
51
  socket.on('error', () => undefined);
52
- socket.on('close', () => { closed = true; });
52
+ socket.on('close', () => {
53
+ closed = true;
54
+ });
53
55
  socket.write(helloFrame(options.token ?? attach.token, options.cols ?? 100, options.rows ?? 30));
54
56
  return {
55
57
  socket,
@@ -57,7 +59,9 @@ export const openViewer = async (attach, options = {}) => {
57
59
  exitCode: () => exitCode,
58
60
  error: () => error,
59
61
  closed: () => closed,
60
- type: (text) => { socket.write(encodeFrame(FrameType.Input, Buffer.from(text + '\r'))); },
62
+ type: (text) => {
63
+ socket.write(encodeFrame(FrameType.Input, Buffer.from(text + '\r')));
64
+ },
61
65
  close: () => socket.destroy(),
62
66
  };
63
67
  };
@@ -77,10 +81,25 @@ export const startDaemon = (t, f, options) => {
77
81
  const { launchPath, data } = options;
78
82
  const output = t.at(path.basename(data) + '-daemon.out');
79
83
  const fd = fs.openSync(output, 'w');
80
- const env = { ...process.env, AGENT_LAUNCH_DIR: launchPath, AGENT_DATA_DIR: data, AGENT_WORKSPACE: options.workspace, AGENT_LOCAL_DIR: f.at(path.basename(data) + '-local'), AGENT_LOG_PREFIX: 'daemon', AGENT_NO_TABS: '1', ...options.env };
81
- const child = spawn(process.execPath, [path.join(launchPath, 'runtime', 'daemon.js')], { env, stdio: ['ignore', fd, fd], windowsHide: true });
84
+ const env = {
85
+ ...process.env,
86
+ AGENT_LAUNCH_DIR: launchPath,
87
+ AGENT_DATA_DIR: data,
88
+ AGENT_WORKSPACE: options.workspace,
89
+ AGENT_LOCAL_DIR: f.at(path.basename(data) + '-local'),
90
+ AGENT_LOG_PREFIX: 'daemon',
91
+ AGENT_NO_TABS: '1',
92
+ ...options.env,
93
+ };
94
+ const child = spawn(process.execPath, [path.join(launchPath, 'runtime', 'daemon.js')], {
95
+ env,
96
+ stdio: ['ignore', fd, fd],
97
+ windowsHide: true,
98
+ });
82
99
  let exited = false;
83
- child.on('exit', () => { exited = true; });
100
+ child.on('exit', () => {
101
+ exited = true;
102
+ });
84
103
  const run = path.join(data, 'run');
85
104
  const status = (id) => readJsonFile(path.join(run, 'sessions', id + '.json'));
86
105
  return {
@@ -89,7 +108,10 @@ export const startDaemon = (t, f, options) => {
89
108
  request: (body) => writeJsonAtomic(path.join(run, 'requests', body.id + '.json'), { createdAt: new Date().toISOString(), ...body }),
90
109
  response: (id, ms = WAIT.response) => t.waitFor(() => readJsonFile(path.join(run, 'responses', id + '.json')), ms),
91
110
  status,
92
- started: (id, ms = WAIT.start) => t.waitFor(() => { const s = status(id); return s && s.phase !== 'starting' ? s : null; }, ms),
111
+ started: (id, ms = WAIT.start) => t.waitFor(() => {
112
+ const s = status(id);
113
+ return s && s.phase !== 'starting' ? s : null;
114
+ }, ms),
93
115
  diagnostics: () => {
94
116
  const logs = path.join(data, 'logs');
95
117
  const files = fs.existsSync(logs) ? fs.readdirSync(logs).filter((n) => n.startsWith('daemon')) : [];
@@ -103,7 +125,9 @@ export const startDaemon = (t, f, options) => {
103
125
  try {
104
126
  fs.closeSync(fd);
105
127
  }
106
- catch { /* already closed */ }
128
+ catch {
129
+ /* already closed */
130
+ }
107
131
  },
108
132
  };
109
133
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,2 +1,2 @@
1
- import type { Suite } from './suite.js';
1
+ import type { Suite } from './support/suite.js';
2
2
  export declare const syncSuite: Suite;
@@ -2,9 +2,10 @@
2
2
  // the sandbox can never send anything but transcripts and databases back.
3
3
  import fs from 'node:fs';
4
4
  import path from 'node:path';
5
- import { syncClaudeMem } from '../sync/claude-mem.js';
6
- import { readSyncState, syncHistoryIn, syncHistoryOut, syncStatePath, translatePaths } from '../sync/history.js';
7
- import { beatLife, endLife, explainStop, lastStopWarning, startLife } from '../host/stops.js';
5
+ import { syncClaudeMem } from '../sync/index.js';
6
+ import { readSyncState, syncStatePath } from '../sync/index.js';
7
+ import { syncHistoryIn, syncHistoryOut, translatePaths } from '../sync/index.js';
8
+ import { crashReportText, explainStop, LifeRecord } from '../host/life/index.js';
8
9
  export const syncSuite = {
9
10
  name: 'sync',
10
11
  title: 'history and claude-mem sync',
@@ -27,11 +28,13 @@ export const syncSuite = {
27
28
  t.check(!fs.existsSync(path.join(guestDot, 'projects', 'C--Other')) && !fs.existsSync(path.join(guestDot, 'todos')), 'history in (scope "project"): other projects\' conversations and session files stay on this PC');
28
29
  const promptIn = fs.readFileSync(path.join(guestDot, 'history.jsonl'), 'utf8');
29
30
  t.includes(promptIn, 'C:\\\\Workspace\\\\my-app', 'prompt history in: project paths are translated');
30
- t.excludes(promptIn, 'secret plan', 'prompt history in: other projects\' prompts stay on this PC');
31
+ t.excludes(promptIn, 'secret plan', "prompt history in: other projects' prompts stay on this PC");
31
32
  const wide = { ...sides, guestClaudeDir: t.at('sync-guest-all') };
32
33
  syncHistoryIn(wide, { scope: 'all' });
33
- t.check(fs.existsSync(path.join(wide.guestClaudeDir, 'projects', 'C--Other', 's2.jsonl')) && fs.existsSync(path.join(wide.guestClaudeDir, 'todos', 's1.json')), 'history in (scope "all"): everything comes in');
34
- // The sandbox adds to the transcript (with a half-written last line), a new transcript, a prompt, and things that must not come back.
34
+ t.check(fs.existsSync(path.join(wide.guestClaudeDir, 'projects', 'C--Other', 's2.jsonl')) &&
35
+ fs.existsSync(path.join(wide.guestClaudeDir, 'todos', 's1.json')), 'history in (scope "all"): everything comes in');
36
+ // The sandbox adds to the transcript (with a half-written last line), a new transcript, a prompt, and things that
37
+ // must not come back.
35
38
  const guestTranscript = path.join(guestProject, 's1.jsonl');
36
39
  fs.appendFileSync(guestTranscript, '{"cwd":"C:\\\\Workspace\\\\my-app","t":2}\n{"partial":');
37
40
  t.touch(guestTranscript);
@@ -69,9 +72,18 @@ export const syncSuite = {
69
72
  t.equal(fs.readFileSync(path.join(hostile.hostClaudeDir, 'history.jsonl'), 'utf8'), '{"display":"ok","timestamp":2,"project":"D:\\\\Code\\\\my-app"}\n', 'only JSON prompt-history entries of this project come back from the sandbox, nothing else it wrote in that file');
70
73
  t.section('sync state file');
71
74
  const stateData = t.at('state-storage', 'data', 'd');
72
- t.writeJson(syncStatePath(stateData), { hostClaudeDir: 'relative\\.claude', hostWorkspace: 'D:\\x', guestWorkspace: 'C:\\x' });
75
+ t.writeJson(syncStatePath(stateData), {
76
+ hostClaudeDir: 'relative\\.claude',
77
+ hostWorkspace: 'D:\\x',
78
+ guestWorkspace: 'C:\\x',
79
+ });
73
80
  t.equal(readSyncState(stateData), null, 'a sync state that points at a relative folder is ignored');
74
- t.writeJson(syncStatePath(stateData), { hostClaudeDir: t.at('c'), hostWorkspace: 'D:\\x', guestWorkspace: 'C:\\x', syncHistory: true });
81
+ t.writeJson(syncStatePath(stateData), {
82
+ hostClaudeDir: t.at('c'),
83
+ hostWorkspace: 'D:\\x',
84
+ guestWorkspace: 'C:\\x',
85
+ syncHistory: true,
86
+ });
75
87
  t.equal(readSyncState(stateData)?.syncHistory, true, 'a valid sync state is read');
76
88
  t.section('claude-mem sync');
77
89
  const memHost = t.at('mem-host');
@@ -83,13 +95,14 @@ export const syncSuite = {
83
95
  t.equal(syncClaudeMem(memHost, memGuest, memState, 'in'), 'copied-in', 'claude-mem in: the folder is copied into the sandbox store');
84
96
  t.equal(fs.readFileSync(path.join(memGuest, 'claude-mem.db'), 'utf8'), 'host-v1', 'claude-mem in: the database arrives');
85
97
  t.check(fs.existsSync(path.join(memGuest, 'chroma', 'index.pickle')), 'claude-mem in: the whole folder arrives, vector store included');
86
- // The sandbox changes its database and plants other files. (Changes are detected by modified time, so make them clearly newer.)
98
+ // The sandbox changes its database and plants other files. (Changes are detected by modified time, so make them
99
+ // clearly newer.)
87
100
  const guestDb = t.write(path.join(memGuest, 'claude-mem.db'), 'guest-v2');
88
101
  t.touch(guestDb, 10);
89
102
  t.write(path.join(memGuest, 'settings.json'), '{"evil":true}');
90
103
  t.write(path.join(memGuest, 'chroma', 'index.pickle'), 'PICKLE-PAYLOAD');
91
104
  t.write(path.join(memGuest, 'payload.exe'), 'MZ');
92
- t.equal(syncClaudeMem(memHost, memGuest, memState, 'out'), 'copied-out', 'claude-mem out: the sandbox\'s database comes back');
105
+ t.equal(syncClaudeMem(memHost, memGuest, memState, 'out'), 'copied-out', "claude-mem out: the sandbox's database comes back");
93
106
  t.equal(fs.readFileSync(hostDb, 'utf8'), 'guest-v2', 'claude-mem out: this PC now has the new database');
94
107
  t.equal(fs.readFileSync(path.join(memHost, 'settings.json'), 'utf8'), '{"host":true}', 'claude-mem out: settings never come back');
95
108
  t.equal(fs.readFileSync(path.join(memHost, 'chroma', 'index.pickle'), 'utf8'), 'host-index', 'claude-mem out: the pickle-based vector store never comes back');
@@ -99,36 +112,61 @@ export const syncSuite = {
99
112
  t.touch(t.write(path.join(memGuest, 'claude-mem.db'), 'guest-v3'), 30);
100
113
  t.touch(t.write(hostDb, 'host-v3'), 30);
101
114
  t.equal(syncClaudeMem(memHost, memGuest, memState, 'out'), 'conflict', 'claude-mem: both sides changed is reported as a conflict');
102
- t.check(fs.readdirSync(t.temp).some((name) => name.startsWith('mem-host.conflict-')), 'claude-mem: this PC\'s database is kept as .conflict-<time> first', fs.readdirSync(t.temp).join(', '));
115
+ t.check(fs.readdirSync(t.temp).some((name) => name.startsWith('mem-host.conflict-')), "claude-mem: this PC's database is kept as .conflict-<time> first", fs.readdirSync(t.temp).join(', '));
103
116
  t.section('how the last sandbox ended');
104
117
  const ev = (id, provider, at, process = '') => ({ id, provider, at, process });
105
- t.equal(explainStop([ev(1074, 'User32', '2026-10-13T02:10:30Z', 'C:\\Windows\\servicing\\TrustedInstaller.exe (HOST)')])?.kind, 'updates', 'a restart by Windows Update is recognised');
118
+ t.equal(explainStop([ev(1074, 'User32', '2026-10-13T02:10:30Z', 'C:\\Windows\\servicing\\TrustedInstaller.exe (HOST)')])
119
+ ?.kind, 'updates', 'a restart by Windows Update is recognised');
106
120
  t.equal(explainStop([ev(1074, 'User32', '2026-10-13T02:10:30Z', 'C:\\Windows\\System32\\winlogon.exe (HOST)')])?.text, 'this PC was restarted or shut down (by winlogon.exe)', 'another restart names the program');
107
- t.equal(explainStop([ev(41, 'Microsoft-Windows-Kernel-Power', '2026-10-13T02:20:00Z'), ev(42, 'Microsoft-Windows-Kernel-Power', '2026-10-13T02:10:00Z')])?.kind, 'sleep', 'the first event counts (sleep, then a crash)');
121
+ t.equal(explainStop([
122
+ ev(41, 'Microsoft-Windows-Kernel-Power', '2026-10-13T02:20:00Z'),
123
+ ev(42, 'Microsoft-Windows-Kernel-Power', '2026-10-13T02:10:00Z'),
124
+ ])?.kind, 'sleep', 'the first event counts (sleep, then a crash)');
108
125
  t.equal(explainStop([ev(2004, 'Microsoft-Windows-Resource-Exhaustion-Detector', '2026-10-13T02:10:00Z')])?.kind, 'memory', 'low memory is recognised');
109
126
  t.equal(explainStop([ev(41, 'SomethingElse', '2026-10-13T02:10:00Z')]), null, 'the same event id from another source is ignored');
110
127
  // The message Hyper-V logged on 13 Oct 2026 when Windows inside the sandbox crashed.
111
128
  const crashMessage = "'8abb707a-972e-42e2-9599-01d125d4595c' has encountered a fatal error. The guest operating system reported that it failed with the following error codes: ErrorCode0: 0x1A, ErrorCode1: 0x13003, ErrorCode2: 0x2346E5, ErrorCode3: 0x1";
112
129
  t.equal(explainStop([ev(18590, 'Microsoft-Windows-Hyper-V-Worker', '2026-10-13T08:49:08Z', crashMessage)])?.text, 'Windows inside the sandbox crashed (stop code 0x1A, 0x13003)', 'a crash of Windows inside the sandbox is recognised, with its stop code');
113
- t.equal(explainStop([ev(24, 'Microsoft-Windows-TerminalServices-LocalSessionManager', '2026-10-13T08:41:40Z', 'PC\\Admin')]), null, 'switching user is not taken for the cause (the sandbox keeps running)');
130
+ t.equal(explainStop([
131
+ ev(24, 'Microsoft-Windows-TerminalServices-LocalSessionManager', '2026-10-13T08:41:40Z', 'PC\\Admin'),
132
+ ]), null, 'switching user is not taken for the cause (the sandbox keeps running)');
133
+ const bugcheck = ev(1001, 'Microsoft-Windows-WER-SystemErrorReporting', '2026-10-13T19:55:00Z', 'The computer has rebooted from a bugcheck. The bugcheck was: 0x0000001a (0x0000000000041792, 0x0, 0x0, 0x0).');
134
+ t.equal(explainStop([bugcheck])?.text, 'this PC blue-screened (stop code 0x0000001a)', 'a blue screen of this PC is recognised, with its stop code');
135
+ const report = crashReportText({
136
+ kind: 'sandboxCrash',
137
+ at: '2026-10-13T08:49:08Z',
138
+ text: 'Windows inside the sandbox crashed (stop code 0x1A, 0x13003)',
139
+ }, [ev(18590, 'Microsoft-Windows-Hyper-V-Worker', '2026-10-13T08:49:08Z', crashMessage)], 'time | RAM\n20:50:28 | 16847/32767 | 23552/49151 | rustc 2535\x1b]52;c;evil\x07\n', '2026-10-13T08:48:30Z');
140
+ t.check(report.includes('stop code 0x1A, 0x13003') &&
141
+ report.includes('Hyper-V-Worker 18590') &&
142
+ report.includes('20:50:28 | 16847/32767'), 'the crash report has what happened, the Windows events and the last memory samples', report);
143
+ t.excludes(report, '\x1b]52', "the sandbox's memory log is shown without escape codes");
114
144
  const lifeRoot = t.at('life-storage');
115
145
  const lifeData = path.join(lifeRoot, 'data', 'testdata');
116
146
  const noEvents = () => null;
117
- t.equal(lastStopWarning(lifeRoot, lifeData, false, noEvents), null, 'no record: nothing to say');
118
- startLife(lifeRoot, lifeData, true, new Date('2026-10-12T20:16:00Z'));
119
- beatLife(lifeRoot, lifeData, new Date('2026-10-13T02:09:00Z'));
120
- t.equal(lastStopWarning(lifeRoot, lifeData, true, noEvents), null, 'its watcher still runs: the sandbox has not ended');
147
+ const life = new LifeRecord(lifeRoot, lifeData);
148
+ t.equal(life.lastStopWarning(false, noEvents), null, 'no record: nothing to say');
149
+ life.start(true, new Date('2026-10-12T20:16:00Z'));
150
+ life.beat(new Date('2026-10-13T02:09:00Z'));
151
+ t.equal(life.lastStopWarning(true, noEvents), null, 'its watcher still runs: the sandbox has not ended');
121
152
  let since = '';
122
- const warning = lastStopWarning(lifeRoot, lifeData, false, (s) => { since = s; return { kind: 'updates', at: '2026-10-13T02:10:30Z', text: 'Windows restarted this PC to install updates' }; });
153
+ const warning = life.lastStopWarning(false, (s) => {
154
+ since = s;
155
+ return { kind: 'updates', at: '2026-10-13T02:10:30Z', text: 'Windows restarted this PC to install updates' };
156
+ });
123
157
  t.includes(warning ?? '', 'Windows restarted this PC to install updates', 'the PC stopped under a running sandbox: the next launch says why');
124
158
  t.includes(warning ?? '', 'Pause updates', '... and what keeps it from happening again');
125
159
  t.equal(since, '2026-10-13T02:09:00.000Z', 'the System log is read from the last time the sandbox was seen running');
126
- t.equal(lastStopWarning(lifeRoot, lifeData, false, noEvents), null, 'said once only');
127
- startLife(lifeRoot, lifeData, true);
128
- endLife(lifeRoot, lifeData, null);
129
- t.equal(lastStopWarning(lifeRoot, lifeData, false, noEvents), null, 'closed while this PC ran (by you): nothing to say');
130
- startLife(lifeRoot, lifeData, true);
131
- endLife(lifeRoot, lifeData, { kind: 'sleep', at: '2026-10-13T02:10:00Z', text: 'this PC went to sleep or hibernated' });
132
- t.includes(lastStopWarning(lifeRoot, lifeData, false, noEvents) ?? '', 'sandbox.keepAwake', 'ended by sleep: the next launch names keepAwake');
160
+ t.equal(life.lastStopWarning(false, noEvents), null, 'said once only');
161
+ life.start(true);
162
+ life.end(null);
163
+ t.equal(life.lastStopWarning(false, noEvents), null, 'closed while this PC ran (by you): nothing to say');
164
+ life.start(true);
165
+ life.end({
166
+ kind: 'sleep',
167
+ at: '2026-10-13T02:10:00Z',
168
+ text: 'this PC went to sleep or hibernated',
169
+ });
170
+ t.includes(life.lastStopWarning(false, noEvents) ?? '', 'sandbox.keepAwake', 'ended by sleep: the next launch names keepAwake');
133
171
  },
134
172
  };
@@ -1,2 +1,2 @@
1
- import type { Suite } from './suite.js';
1
+ import type { Suite } from './support/suite.js';
2
2
  export declare const testGuardSuite: Suite;
@@ -4,41 +4,69 @@
4
4
  import fs from 'node:fs';
5
5
  import os from 'node:os';
6
6
  import path from 'node:path';
7
- import { saveAccount } from '../host/accounts.js';
8
- import { sendRequest } from '../host/channel.js';
9
- import { hostClaude, spawnDetached, startSandbox } from '../host/platform.js';
10
- import { hideSandboxWindow, showSandboxWindow } from '../host/window.js';
11
- import { ensureTerminal, syncPwshProfile } from '../host/terminal.js';
12
- import { safeRemove } from '../shared/safe-remove.js';
13
- import { writeJsonAtomic } from '../shared/rundir.js';
14
- import { syncClaudeMem } from '../sync/claude-mem.js';
15
- import { syncHistoryIn, syncHistoryOut } from '../sync/history.js';
16
- import { watch } from '../sync/watcher.js';
7
+ import { AccountStore } from '../host/profile/index.js';
8
+ import { SandboxChannel } from '../host/channel/index.js';
9
+ import { hostClaude } from '../host/sandbox/index.js';
10
+ import { spawnDetached, startSandbox } from '../host/sandbox/index.js';
11
+ import { hideSandboxWindow, showSandboxWindow } from '../host/sandbox/index.js';
12
+ import { ensureTerminal, syncPwshProfile } from '../host/tools/index.js';
13
+ import { safeRemove } from '../shared/io/index.js';
14
+ import { writeJsonAtomic } from '../shared/io/index.js';
15
+ import { syncClaudeMem } from '../sync/index.js';
16
+ import { syncHistoryIn, syncHistoryOut } from '../sync/index.js';
17
+ import { watch } from '../sync/index.js';
17
18
  export const testGuardSuite = {
18
19
  name: 'test-guard',
19
20
  title: 'the self-test refuses to act on this PC',
20
21
  run: async (t) => {
21
22
  t.check(process.env.AGENT_SANDBOX_SELFTEST === '1', 'the self-test guard is switched on for the whole run');
22
23
  const real = path.join(os.homedir(), 'agent-sandbox-selftest-guard-probe');
23
- const sides = { hostClaudeDir: real, guestClaudeDir: t.at('guard-guest'), hostWorkspace: 'D:\\Code\\my-app', guestWorkspace: 'C:\\Workspace\\my-app' };
24
+ const sides = {
25
+ hostClaudeDir: real,
26
+ guestClaudeDir: t.at('guard-guest'),
27
+ hostWorkspace: 'D:\\Code\\my-app',
28
+ guestWorkspace: 'C:\\Workspace\\my-app',
29
+ };
24
30
  const guardData = t.at('guard-data', 'data', 'd');
25
31
  const login = t.write(t.at('guard-login', '.credentials.json'), '{"claudeAiOauth":{}}');
26
32
  const blocked = [
27
33
  ['start Windows Sandbox', () => startSandbox(t.at('storage', 'agent.wsb'))],
28
- ['start the background watcher process', () => spawnDetached(path.join(t.packageRoot, 'dist', 'bin', 'sandbox.js'), ['_watch'])],
34
+ [
35
+ 'start the background watcher process',
36
+ () => spawnDetached(path.join(t.packageRoot, 'dist', 'bin', 'sandbox.js'), ['_watch']),
37
+ ],
29
38
  ['run Claude Code on this PC', () => hostClaude(t.at('storage'), false, ['--version'])],
30
39
  ['hide windows', () => hideSandboxWindow(t.at('storage'), 1)],
31
40
  ['show windows', () => showSandboxWindow(t.at('storage'))],
32
- ['shut down Windows Sandbox', () => sendRequest(guardData, { kind: 'exec', id: 'sd', command: ['C:\\Windows\\System32\\shutdown.exe', '/s'], cwd: 'C:\\', timeoutSeconds: 5, createdAt: '' })],
41
+ [
42
+ 'shut down Windows Sandbox',
43
+ () => new SandboxChannel(guardData).send({
44
+ kind: 'exec',
45
+ id: 'sd',
46
+ command: ['C:\\Windows\\System32\\shutdown.exe', '/s'],
47
+ cwd: 'C:\\',
48
+ timeoutSeconds: 5,
49
+ createdAt: '',
50
+ }),
51
+ ],
33
52
  ['start the background sync', () => watch(t.at('storage', 'data', 'w'))],
34
53
  ['write Windows Terminal settings', () => syncPwshProfile(real, true)],
35
54
  ['download Windows Terminal into a profile', () => ensureTerminal(real, true)],
36
55
  ['sync history into the real profile', () => syncHistoryOut(sides)],
37
56
  ['sync history into the sandbox state in a profile', () => syncHistoryIn({ ...sides, guestClaudeDir: real })],
38
- ['sync claude-mem into the real profile', () => syncClaudeMem(real, t.at('mem-store'), { hostClaudeDir: real, hostWorkspace: 'D:\\x', guestWorkspace: 'C:\\x' }, 'out')],
57
+ [
58
+ 'sync claude-mem into the real profile',
59
+ () => syncClaudeMem(real, t.at('mem-store'), { hostClaudeDir: real, hostWorkspace: 'D:\\x', guestWorkspace: 'C:\\x' }, 'out'),
60
+ ],
39
61
  ['write a state file in a profile', () => writeJsonAtomic(path.join(real, 'x.json'), {})],
40
62
  ['delete in a profile', () => safeRemove(path.join(real, 'x'), os.homedir())],
41
- ['save a login into a profile', () => saveAccount(real, t.at('acct-storage', 'data', 'd'), 'work', { claudeDir: path.dirname(login), globalStateFile: t.at('guard-login', '.claude.json') })],
63
+ [
64
+ 'save a login into a profile',
65
+ () => new AccountStore(real).save(t.at('acct-storage', 'data', 'd'), 'work', {
66
+ claudeDir: path.dirname(login),
67
+ globalStateFile: t.at('guard-login', '.claude.json'),
68
+ }),
69
+ ],
42
70
  ];
43
71
  for (const [what, action] of blocked)
44
72
  await t.throws(async () => action(), /self-test/i, 'self-test mode refuses to ' + what);
@@ -1,2 +1,2 @@
1
- import type { Suite } from './suite.js';
1
+ import type { Suite } from './support/suite.js';
2
2
  export declare const toolchainsSuite: Suite;
@@ -1,51 +1,97 @@
1
1
  // Picking tool versions and release assets: Node/Go/Python/Java version rules, GitHub release pages, PowerShell 7,
2
2
  // cargo-binstall, the small CLI tools (gh, zstd, openssl), and when PowerShell 7 is wanted.
3
3
  import path from 'node:path';
4
- import { javaMajorFrom, pickGoRelease, pickNodeVersion, pickPackageVersion, pickSpreadVersions, projectUses, specFromVersionFile } from '../guest/toolchains/versions.js';
5
- import { parseReleasePage, parseReleaseTags } from '../shared/download.js';
6
- import { decidePwsh, pcHasPwsh, PWSH_MAX_BYTES, readPwshScripts, usesPwsh } from '../core/detect-pwsh.js';
4
+ import { javaMajorFrom, pickGoRelease, pickNodeVersion, pickPackageVersion, pickSpreadVersions, projectUses, specFromVersionFile, } from '../core/detect/index.js';
5
+ import { parseReleasePage, parseReleaseTags } from '../shared/download/index.js';
6
+ import { decidePwsh, pcHasPwsh, PWSH_MAX_BYTES, readPwshScripts, usesPwsh } from '../core/detect/index.js';
7
7
  import { binstallAsset, CLI_TOOLS, decideCli, pwshAsset } from '../guest/toolchains/catalogue.js';
8
- import { missingExtensions, vscodeExtensions, vscodeSettings } from '../guest/toolchains/vscode-profile.js';
9
- import { APP_CATEGORIES, APPS, appsNeedMesa, appsToInstall, exeMatcher } from '../shared/apps.js';
10
- import { Config, LocalOverrides } from '../core/schema.js';
8
+ import { missingExtensions, vscodeExtensions, vscodeSettings } from '../guest/toolchains/tools/vscode-profile.js';
9
+ import { APP_CATEGORIES, APPS, appsNeedMesa, appsToInstall, exeMatcher } from '../shared/apps/index.js';
10
+ import { ConfigSchema, LocalOverridesSchema } from '../core/schema/index.js';
11
11
  export const toolchainsSuite = {
12
12
  name: 'toolchains',
13
13
  title: 'version pickers, release assets, PowerShell 7 and CLI tool decisions',
14
14
  run: (t) => {
15
15
  t.section('version pickers');
16
- const releases = [{ version: 'v23.1.0', lts: false }, { version: 'v22.11.0', lts: 'Jod' }, { version: 'v20.18.0', lts: 'Iron' }, { version: 'v20.9.0', lts: 'Iron' }];
16
+ const releases = [
17
+ { version: 'v23.1.0', lts: false },
18
+ { version: 'v22.11.0', lts: 'Jod' },
19
+ { version: 'v20.18.0', lts: 'Iron' },
20
+ { version: 'v20.9.0', lts: 'Iron' },
21
+ ];
17
22
  const node = (spec) => pickNodeVersion(releases, spec);
18
23
  t.equal([node('lts/*'), node('lts/iron'), node('20'), node('v20.9.0'), node('node'), node('99')], ['22.11.0', '20.18.0', '20.18.0', '20.9.0', '23.1.0', null], '.nvmrc specs resolve (lts/*, lts/<name>, major, exact, node)');
19
24
  const installed = ['16.20.2', '18.19.0', '18.20.4', '20.18.0', '22.3.0', '22.11.0', '23.1.0', 'notes'];
20
25
  t.equal(pickSpreadVersions(installed, '22.11.0', 3), ['22.11.0', '16.20.2', '23.1.0'], 'host nvm versions: capped, the current one first, the rest spread across other majors');
21
26
  t.equal(pickSpreadVersions(['20.18.0'], '22.3.0', 3), ['22.3.0', '20.18.0'], 'host nvm versions: a missing current version is added first');
22
27
  t.equal(pickSpreadVersions(['18.20.4', '20.18.0'], '22.3.0', 1), ['22.3.0'], 'host nvm versions: the cap wins');
23
- const go = [{ version: 'go1.24rc1', stable: false, files: [] }, { version: 'go1.23.2', stable: true, files: [] }, { version: 'go1.23.1', stable: true, files: [] }, { version: 'go1.22.8', stable: true, files: [] }];
24
- t.equal([pickGoRelease(go, 'stable')?.version, pickGoRelease(go, '1.22')?.version, pickGoRelease(go, 'go1.23.1')?.version, pickGoRelease(go, '1.30')], ['go1.23.2', 'go1.22.8', 'go1.23.1', null], 'Go versions resolve (stable, minor prefix, exact); release candidates are skipped');
25
- t.equal([javaMajorFrom('21\n'), javaMajorFrom('17.0.9'), javaMajorFrom('1.8'), javaMajorFrom('temurin-21.0.2'), javaMajorFrom('# sdkman\njava=21.0.2-tem\n', true)], ['21', '17', '8', '21', '21'], 'version files: .java-version and .sdkmanrc');
28
+ const go = [
29
+ { version: 'go1.24rc1', stable: false, files: [] },
30
+ { version: 'go1.23.2', stable: true, files: [] },
31
+ { version: 'go1.23.1', stable: true, files: [] },
32
+ { version: 'go1.22.8', stable: true, files: [] },
33
+ ];
34
+ t.equal([
35
+ pickGoRelease(go, 'stable')?.version,
36
+ pickGoRelease(go, '1.22')?.version,
37
+ pickGoRelease(go, 'go1.23.1')?.version,
38
+ pickGoRelease(go, '1.30'),
39
+ ], ['go1.23.2', 'go1.22.8', 'go1.23.1', null], 'Go versions resolve (stable, minor prefix, exact); release candidates are skipped');
40
+ t.equal([
41
+ javaMajorFrom('21\n'),
42
+ javaMajorFrom('17.0.9'),
43
+ javaMajorFrom('1.8'),
44
+ javaMajorFrom('temurin-21.0.2'),
45
+ javaMajorFrom('# sdkman\njava=21.0.2-tem\n', true),
46
+ ], ['21', '17', '8', '21', '21'], 'version files: .java-version and .sdkmanrc');
26
47
  t.equal(specFromVersionFile('ruby-3.3.1\n'), '3.3.1', 'version files: .ruby-version');
27
48
  t.check(projectUses(['README.md', 'server/go.mod'], ['go.mod']) && projectUses(['App.csproj'], ['*.csproj']), 'enabled "auto": a language is used when its marker file is in the workspace or one folder down');
28
49
  t.check(!projectUses(['notes.txt', 'docs/readme.md'], ['go.mod', '*.csproj']), 'enabled "auto": a language is not used without its marker file');
29
50
  const python = ['3.9.13', '3.12.7', '3.12.10', '3.13.0-rc1', '3.13.1'];
30
- t.equal([pickPackageVersion(python, '3'), pickPackageVersion(['3.12.7', '3.12.10'], '3.12'), pickPackageVersion(['2.7.18'], '2.7')], ['3.13.1', '3.12.10', '2.7.18'], 'Python versions resolve to the newest stable match');
51
+ t.equal([
52
+ pickPackageVersion(python, '3'),
53
+ pickPackageVersion(['3.12.7', '3.12.10'], '3.12'),
54
+ pickPackageVersion(['2.7.18'], '2.7'),
55
+ ], ['3.13.1', '3.12.10', '2.7.18'], 'Python versions resolve to the newest stable match');
31
56
  t.section('GitHub release pages (the fallback when the API is rate limited)');
32
57
  const tags = '<a href="/coreybutler/nvm-windows/releases/tag/1.2.2">x</a><a href="/coreybutler/nvm-windows/releases/tag/1.2.2">y</a><a href="/other/repo/releases/tag/9">z</a><a href="/coreybutler/nvm-windows/releases/tag/1.1.12">w</a>';
33
- t.equal(parseReleaseTags(tags, 'coreybutler/nvm-windows'), ['1.2.2', '1.1.12'], 'release list page: this repo\'s tags in order, once each');
34
- const page = '<a href="/o/r/releases/download/v1/tool-win-x64.zip">x</a><span>sha256:' + 'a'.repeat(64) + '</span><a href="/o/r/releases/download/v1/tool-linux.tar.gz">y</a>';
58
+ t.equal(parseReleaseTags(tags, 'coreybutler/nvm-windows'), ['1.2.2', '1.1.12'], "release list page: this repo's tags in order, once each");
59
+ const page = '<a href="/o/r/releases/download/v1/tool-win-x64.zip">x</a><span>sha256:' +
60
+ 'a'.repeat(64) +
61
+ '</span><a href="/o/r/releases/download/v1/tool-linux.tar.gz">y</a>';
35
62
  const assets = parseReleasePage(page);
36
63
  t.equal(assets.length, 2, 'release page: both assets are found');
37
64
  t.equal(assets[0].url, 'https://github.com/o/r/releases/download/v1/tool-win-x64.zip', 'release page: asset links become full URLs');
38
- t.equal([assets[0].sha256, assets[1].sha256], ['a'.repeat(64), null], 'release page: only an asset\'s own sha256 is used');
65
+ t.equal([assets[0].sha256, assets[1].sha256], ['a'.repeat(64), null], "release page: only an asset's own sha256 is used");
39
66
  t.section('release assets per architecture');
40
67
  const matching = (pattern, names) => names.filter((n) => pattern.test(n));
41
- const pwshNames = ['PowerShell-7.6.6-win-x64.zip', 'PowerShell-7.6.6-win-arm64.zip', 'PowerShell-7.6.6-win-x64.msi', 'PowerShell-7.6.6-win-fxdependent.zip', 'PowerShell-7.6.6-win-x86.zip', 'PowerShell-7.6.6-win-x64.zip.sha256'];
68
+ const pwshNames = [
69
+ 'PowerShell-7.6.6-win-x64.zip',
70
+ 'PowerShell-7.6.6-win-arm64.zip',
71
+ 'PowerShell-7.6.6-win-x64.msi',
72
+ 'PowerShell-7.6.6-win-fxdependent.zip',
73
+ 'PowerShell-7.6.6-win-x86.zip',
74
+ 'PowerShell-7.6.6-win-x64.zip.sha256',
75
+ ];
42
76
  t.equal(matching(pwshAsset('x64'), pwshNames), ['PowerShell-7.6.6-win-x64.zip'], 'PowerShell 7 (x64): the portable zip, not the MSI, fxdependent or x86 build');
43
77
  t.equal(matching(pwshAsset('arm64'), pwshNames), ['PowerShell-7.6.6-win-arm64.zip'], 'PowerShell 7 (arm64): the portable zip');
44
- const binstallNames = ['cargo-binstall-x86_64-pc-windows-msvc.zip', 'cargo-binstall-x86_64-pc-windows-msvc.full.zip', 'cargo-binstall-x86_64-pc-windows-msvc.zip.sig', 'cargo-binstall-aarch64-pc-windows-msvc.zip', 'cargo-binstall-x86_64-unknown-linux-musl.tgz'];
78
+ const binstallNames = [
79
+ 'cargo-binstall-x86_64-pc-windows-msvc.zip',
80
+ 'cargo-binstall-x86_64-pc-windows-msvc.full.zip',
81
+ 'cargo-binstall-x86_64-pc-windows-msvc.zip.sig',
82
+ 'cargo-binstall-aarch64-pc-windows-msvc.zip',
83
+ 'cargo-binstall-x86_64-unknown-linux-musl.tgz',
84
+ ];
45
85
  t.equal(matching(binstallAsset('x64'), binstallNames), ['cargo-binstall-x86_64-pc-windows-msvc.zip'], 'cargo-binstall (x64): the plain Windows zip, not .full or the signature');
46
86
  t.equal(matching(binstallAsset('arm64'), binstallNames), ['cargo-binstall-aarch64-pc-windows-msvc.zip'], 'cargo-binstall (arm64): the plain Windows zip');
47
87
  const cliAsset = (name, arch, names) => matching(CLI_TOOLS.find((c) => c.name === name).asset(arch), names);
48
- const ghNames = ['gh_2.102.0_windows_amd64.zip', 'gh_2.102.0_windows_amd64.msi', 'gh_2.102.0_windows_386.zip', 'gh_2.102.0_windows_arm64.zip', 'gh_2.102.0_linux_amd64.tar.gz'];
88
+ const ghNames = [
89
+ 'gh_2.102.0_windows_amd64.zip',
90
+ 'gh_2.102.0_windows_amd64.msi',
91
+ 'gh_2.102.0_windows_386.zip',
92
+ 'gh_2.102.0_windows_arm64.zip',
93
+ 'gh_2.102.0_linux_amd64.tar.gz',
94
+ ];
49
95
  const zstdNames = ['zstd-v1.5.7-win64.zip', 'zstd-v1.5.7-win32.zip', 'zstd-v1.5.7.tar.gz'];
50
96
  t.equal(cliAsset('gh', 'x64', ghNames), ['gh_2.102.0_windows_amd64.zip'], 'CLI catalogue: gh zip for x64');
51
97
  t.equal(cliAsset('gh', 'arm64', ghNames), ['gh_2.102.0_windows_arm64.zip'], 'CLI catalogue: gh zip for arm64');
@@ -53,7 +99,10 @@ export const toolchainsSuite = {
53
99
  t.equal(cliAsset('zstd', 'arm64', zstdNames), ['zstd-v1.5.7-win64.zip'], 'CLI catalogue: zstd win64 also serves Arm');
54
100
  t.check(CLI_TOOLS.every((c) => c.exe.endsWith('.exe')), 'CLI catalogue: every tool is an .exe');
55
101
  t.section('which CLI tools are installed');
56
- const cli = (settings, gitAccess, hasGithubDir = false) => Object.entries(decideCli(settings, { gitAccess, hasGithubDir })).filter(([, d]) => d.on).map(([n]) => n).join();
102
+ const cli = (settings, gitAccess, hasGithubDir = false) => Object.entries(decideCli(settings, { gitAccess, hasGithubDir }))
103
+ .filter(([, d]) => d.on)
104
+ .map(([n]) => n)
105
+ .join();
57
106
  t.equal(cli({ gh: true, zstd: true, openssl: true }, 'full'), 'gh,zstd,openssl', 'CLI tools: everything asked for is installed with git access "full"');
58
107
  t.equal(cli({ gh: true, zstd: true }, 'readonly'), 'zstd', 'CLI tools: gh needs git access "full" (it pushes through the API), whatever the config says');
59
108
  t.equal(cli({ gh: 'auto' }, 'none', true), '', 'CLI tools: no git access, no gh');
@@ -77,7 +126,14 @@ export const toolchainsSuite = {
77
126
  t.equal(ps('Write-Host hi'), null, 'not a marker: an ordinary script');
78
127
  // Hostile scripts (a cloned repository is untrusted): capped and scanned in linear time.
79
128
  const evilStart = Date.now();
80
- const evilText = (' #requires' + ' -version'.repeat(5000) + '\n' + 'xpwsh pwsh\t\t'.repeat(20000) + '\n' + ' '.repeat(100000) + 'pwsh\n' + 'pwsh\n'.repeat(50000)).repeat(3);
129
+ const evilText = (' #requires' +
130
+ ' -version'.repeat(5000) +
131
+ '\n' +
132
+ 'xpwsh pwsh\t\t'.repeat(20000) +
133
+ '\n' +
134
+ ' '.repeat(100000) +
135
+ 'pwsh\n' +
136
+ 'pwsh\n'.repeat(50000)).repeat(3);
81
137
  const evil = usesPwsh(Array.from({ length: 100 }, (_, i) => ({ path: 'a' + i + '.ps1', text: evilText })));
82
138
  const evilMs = Date.now() - evilStart;
83
139
  t.equal(evil, null, 'hostile scripts (huge lines, endless repeats) do not match');
@@ -103,31 +159,74 @@ export const toolchainsSuite = {
103
159
  t.equal(scanned.map((s) => s.path), ['moh.ps1', 'scripts/build.ps1'], 'pwsh scan: *.ps1 at the root and one folder down only (node_modules skipped)');
104
160
  t.equal(scanned[1].text.length, PWSH_MAX_BYTES, 'pwsh scan: each script is read up to its cap');
105
161
  t.section('VS Code set-up');
106
- const vs = vscodeSettings({ javaHome: 'C:\\t\\java\\jdk-17.0.9+9', python: 'C:\\t\\python\\python.exe', pwsh: 'C:\\t\\pwsh\\pwsh.exe', gcc: 'C:\\t\\mingw\\bin\\gcc.exe', cl: 'C:\\t\\msvc\\cl.exe', dotnet: 'C:\\t\\dotnet\\dotnet.exe' });
107
- t.equal([vs['java.jdt.ls.java.home'], vs['java.configuration.runtimes'][0].name, vs['python.defaultInterpreterPath'], vs['terminal.integrated.defaultProfile.windows'], vs['C_Cpp.default.compilerPath'], vs['dotnet.dotnetPath']], ['C:\\t\\java\\jdk-17.0.9+9', 'JavaSE-17', 'C:\\t\\python\\python.exe', 'PowerShell 7', 'C:\\t\\msvc\\cl.exe', 'C:\\t\\dotnet'], 'vscode: settings point at the sandbox\'s JDK (with its version), Python, PowerShell 7, compiler (MSVC first) and .NET');
162
+ const vs = vscodeSettings({
163
+ javaHome: 'C:\\t\\java\\jdk-17.0.9+9',
164
+ python: 'C:\\t\\python\\python.exe',
165
+ pwsh: 'C:\\t\\pwsh\\pwsh.exe',
166
+ gcc: 'C:\\t\\mingw\\bin\\gcc.exe',
167
+ cl: 'C:\\t\\msvc\\cl.exe',
168
+ dotnet: 'C:\\t\\dotnet\\dotnet.exe',
169
+ });
170
+ t.equal([
171
+ vs['java.jdt.ls.java.home'],
172
+ vs['java.configuration.runtimes'][0].name,
173
+ vs['python.defaultInterpreterPath'],
174
+ vs['terminal.integrated.defaultProfile.windows'],
175
+ vs['C_Cpp.default.compilerPath'],
176
+ vs['dotnet.dotnetPath'],
177
+ ], [
178
+ 'C:\\t\\java\\jdk-17.0.9+9',
179
+ 'JavaSE-17',
180
+ 'C:\\t\\python\\python.exe',
181
+ 'PowerShell 7',
182
+ 'C:\\t\\msvc\\cl.exe',
183
+ 'C:\\t\\dotnet',
184
+ ], "vscode: settings point at the sandbox's JDK (with its version), Python, PowerShell 7, compiler (MSVC first) and .NET");
108
185
  t.check(!('go.goroot' in vs) && !('git.path' in vs), 'vscode: tools that are not installed are not set');
109
- const ext = vscodeExtensions({ toolchains: ['node', 'java'], databases: ['postgres'], recommended: ['Foo.Bar', 'not an id'], extra: ['eamodio.gitlens', 'redhat.java'] });
110
- t.check(ext.includes('redhat.java') && ext.includes('mtxr.sqltools-driver-pg') && ext.includes('foo.bar') && ext.includes('eamodio.gitlens') && !ext.includes('not an id') && ext.filter((e) => e === 'redhat.java').length === 1, 'vscode: extensions for the languages and databases in use, the project\'s and yours (no duplicates, nothing malformed)');
186
+ const ext = vscodeExtensions({
187
+ toolchains: ['node', 'java'],
188
+ databases: ['postgres'],
189
+ recommended: ['Foo.Bar', 'not an id'],
190
+ extra: ['eamodio.gitlens', 'redhat.java'],
191
+ });
192
+ t.check(ext.includes('redhat.java') &&
193
+ ext.includes('mtxr.sqltools-driver-pg') &&
194
+ ext.includes('foo.bar') &&
195
+ ext.includes('eamodio.gitlens') &&
196
+ !ext.includes('not an id') &&
197
+ ext.filter((e) => e === 'redhat.java').length === 1, "vscode: extensions for the languages and databases in use, the project's and yours (no duplicates, nothing malformed)");
111
198
  t.equal(missingExtensions(['golang.go', 'redhat.java'], ['golang.go-0.48.0', 'extensions.json']), ['redhat.java'], 'vscode: only extensions not installed yet are downloaded');
112
199
  t.section('apps catalogue');
113
200
  const ids = APPS.map((a) => a.id);
114
201
  t.equal(ids.filter((id, i) => ids.indexOf(id) !== i), [], 'apps: every id is unique');
115
202
  t.equal(APPS.filter((a) => !APP_CATEGORIES.some((c) => c.id === a.category)).map((a) => a.id), [], 'apps: every app is in a known category');
116
- t.equal(APPS.filter((a) => 'github' in a.source && (() => { try {
117
- new RegExp(a.source.asset);
118
- return false;
119
- }
120
- catch {
121
- return true;
122
- } })()).map((a) => a.id), [], 'apps: every GitHub asset pattern compiles');
123
- t.check(exeMatcher('/^Godot_v[\\d.]+-stable_win64\\.exe$/')('Godot_v4.7.2-stable_win64.exe') && !exeMatcher('/^Godot_v[\\d.]+-stable_win64\\.exe$/')('Godot_v4.7.2-stable_win64_console.exe') && exeMatcher('Code.exe')('code.EXE'), 'apps: the program is found by name or by pattern');
124
- const chosen = appsToInstall({ install: ['firefox', 'jq', 'githubdesktop'], custom: { mine: { name: 'Mine', url: 'https://example.com/m.zip', exe: 'm.exe' } } }, 'readonly');
203
+ t.equal(APPS.filter((a) => 'github' in a.source &&
204
+ (() => {
205
+ try {
206
+ new RegExp(a.source.asset);
207
+ return false;
208
+ }
209
+ catch {
210
+ return true;
211
+ }
212
+ })()).map((a) => a.id), [], 'apps: every GitHub asset pattern compiles');
213
+ t.check(exeMatcher('/^Godot_v[\\d.]+-stable_win64\\.exe$/')('Godot_v4.7.2-stable_win64.exe') &&
214
+ !exeMatcher('/^Godot_v[\\d.]+-stable_win64\\.exe$/')('Godot_v4.7.2-stable_win64_console.exe') &&
215
+ exeMatcher('Code.exe')('code.EXE'), 'apps: the program is found by name or by pattern');
216
+ const chosen = appsToInstall({
217
+ install: ['firefox', 'jq', 'githubdesktop'],
218
+ custom: { mine: { name: 'Mine', url: 'https://example.com/m.zip', exe: 'm.exe' } },
219
+ }, 'readonly');
125
220
  t.equal(chosen.entries.map((e) => e.id), ['7zip', 'firefox', 'jq', 'custom/mine'], 'apps: 7-Zip comes first when an installer needs it; your own programs follow');
126
221
  t.equal(chosen.skipped.length, 1, 'apps: an app with its own git (GitHub Desktop) is skipped unless git access is "full"');
127
222
  t.check(appsNeedMesa({ install: ['godot'], custom: {} }) && !appsNeedMesa({ install: ['jq'], custom: {} }), 'apps: game engines bring Mesa (OpenGL without a GPU) along');
128
- const custom = (app) => Config.shape.apps.shape.custom.safeParse({ x: app }).success;
129
- t.check(custom({ name: 'A', github: 'o/r', asset: 'win.*\\.zip$', exe: 'a.exe' }) && custom({ name: 'B', url: 'https://x.org/b.zip', exe: 'b.exe' }), 'apps: your own program comes from a GitHub release or an https link');
130
- t.check(!custom({ name: 'C', url: 'http://x.org/c.zip', exe: 'c.exe' }) && !custom({ name: 'D', github: 'o/r', asset: '(', exe: 'd.exe' }) && !custom({ name: 'E', github: 'o/r', asset: 'x', url: 'https://x.org', exe: 'e.exe' }), 'apps: plain http, a broken pattern, or both sources are refused');
131
- t.check(!LocalOverrides.safeParse({ apps: { custom: {} } }).success && LocalOverrides.safeParse({ apps: { install: ['jq'] } }).success, 'apps: a project file may add catalogue apps but never programs of its own');
223
+ const custom = (app) => ConfigSchema.shape.apps.shape.custom.safeParse({ x: app }).success;
224
+ t.check(custom({ name: 'A', github: 'o/r', asset: 'win.*\\.zip$', exe: 'a.exe' }) &&
225
+ custom({ name: 'B', url: 'https://x.org/b.zip', exe: 'b.exe' }), 'apps: your own program comes from a GitHub release or an https link');
226
+ t.check(!custom({ name: 'C', url: 'http://x.org/c.zip', exe: 'c.exe' }) &&
227
+ !custom({ name: 'D', github: 'o/r', asset: '(', exe: 'd.exe' }) &&
228
+ !custom({ name: 'E', github: 'o/r', asset: 'x', url: 'https://x.org', exe: 'e.exe' }), 'apps: plain http, a broken pattern, or both sources are refused');
229
+ t.check(!LocalOverridesSchema.safeParse({ apps: { custom: {} } }).success &&
230
+ LocalOverridesSchema.safeParse({ apps: { install: ['jq'] } }).success, 'apps: a project file may add catalogue apps but never programs of its own');
132
231
  },
133
232
  };
@@ -1,2 +1,2 @@
1
- import type { Suite } from './suite.js';
1
+ import type { Suite } from './support/suite.js';
2
2
  export declare const workspaceViewSuite: Suite;