@withbuddi/buddi 0.1.0-pre.52 → 0.1.0-pre.54

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 (552) hide show
  1. package/extension/background.js +38 -7
  2. package/extension/manifest.json +2 -2
  3. package/extension/popup.html +2 -2
  4. package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
  5. package/node_modules/@buddi/cli/dist/dashboard-cmd.d.ts.map +1 -1
  6. package/node_modules/@buddi/cli/dist/dashboard-cmd.js +6 -3
  7. package/node_modules/@buddi/cli/dist/dashboard-cmd.js.map +1 -1
  8. package/node_modules/@buddi/cli/dist/main.js +2 -2
  9. package/node_modules/@buddi/cli/dist/main.js.map +1 -1
  10. package/node_modules/@buddi/cli/dist/status.d.ts +16 -2
  11. package/node_modules/@buddi/cli/dist/status.d.ts.map +1 -1
  12. package/node_modules/@buddi/cli/dist/status.js +42 -2
  13. package/node_modules/@buddi/cli/dist/status.js.map +1 -1
  14. package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
  15. package/node_modules/@buddi/core/dist/agents/catalog.d.ts +6 -0
  16. package/node_modules/@buddi/core/dist/agents/catalog.d.ts.map +1 -1
  17. package/node_modules/@buddi/core/dist/agents/catalog.js +1 -1
  18. package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
  19. package/node_modules/@buddi/core/dist/backup/archive.d.ts +6 -0
  20. package/node_modules/@buddi/core/dist/backup/archive.d.ts.map +1 -1
  21. package/node_modules/@buddi/core/dist/backup/archive.js +19 -6
  22. package/node_modules/@buddi/core/dist/backup/archive.js.map +1 -1
  23. package/node_modules/@buddi/core/dist/postgres/binaries.d.ts +21 -1
  24. package/node_modules/@buddi/core/dist/postgres/binaries.d.ts.map +1 -1
  25. package/node_modules/@buddi/core/dist/postgres/binaries.js +72 -10
  26. package/node_modules/@buddi/core/dist/postgres/binaries.js.map +1 -1
  27. package/node_modules/@buddi/core/dist/postgres/cluster.d.ts +8 -0
  28. package/node_modules/@buddi/core/dist/postgres/cluster.d.ts.map +1 -1
  29. package/node_modules/@buddi/core/dist/postgres/cluster.js +119 -17
  30. package/node_modules/@buddi/core/dist/postgres/cluster.js.map +1 -1
  31. package/node_modules/@buddi/core/dist/postgres/windows-guard.d.ts +20 -0
  32. package/node_modules/@buddi/core/dist/postgres/windows-guard.d.ts.map +1 -0
  33. package/node_modules/@buddi/core/dist/postgres/windows-guard.js +140 -0
  34. package/node_modules/@buddi/core/dist/postgres/windows-guard.js.map +1 -0
  35. package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
  36. package/node_modules/@buddi/gateway/dist/agents/catalog.d.ts.map +1 -1
  37. package/node_modules/@buddi/gateway/dist/agents/catalog.js +3 -2
  38. package/node_modules/@buddi/gateway/dist/agents/catalog.js.map +1 -1
  39. package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts +2 -2
  40. package/node_modules/@buddi/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
  41. package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js +1 -1
  42. package/node_modules/@buddi/gateway/dist/agents/catalogue-package.js.map +1 -1
  43. package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts +6 -6
  44. package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
  45. package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js +5 -5
  46. package/node_modules/@buddi/gateway/dist/agents/platform-catalogue.js.map +1 -1
  47. package/node_modules/@buddi/gateway/dist/browser-host.js +1 -1
  48. package/node_modules/@buddi/gateway/dist/browser-host.js.map +1 -1
  49. package/node_modules/@buddi/gateway/dist/missions/chrome-scope.d.ts +10 -10
  50. package/node_modules/@buddi/gateway/dist/missions/chrome-scope.d.ts.map +1 -1
  51. package/node_modules/@buddi/gateway/dist/missions/chrome-scope.js +20 -20
  52. package/node_modules/@buddi/gateway/dist/missions/chrome-scope.js.map +1 -1
  53. package/node_modules/@buddi/gateway/dist/missions/execute.d.ts +2 -2
  54. package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
  55. package/node_modules/@buddi/gateway/dist/missions/execute.js +11 -11
  56. package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
  57. package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts +2 -2
  58. package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts.map +1 -1
  59. package/node_modules/@buddi/gateway/dist/missions/reminders.js +5 -5
  60. package/node_modules/@buddi/gateway/dist/missions/reminders.js.map +1 -1
  61. package/node_modules/@buddi/gateway/dist/owner-notify.js +1 -1
  62. package/node_modules/@buddi/gateway/dist/owner-notify.js.map +1 -1
  63. package/node_modules/@buddi/gateway/dist/plugins/npm.d.ts +9 -2
  64. package/node_modules/@buddi/gateway/dist/plugins/npm.d.ts.map +1 -1
  65. package/node_modules/@buddi/gateway/dist/plugins/npm.js +29 -6
  66. package/node_modules/@buddi/gateway/dist/plugins/npm.js.map +1 -1
  67. package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts.map +1 -1
  68. package/node_modules/@buddi/gateway/dist/plugins/stage.js +2 -2
  69. package/node_modules/@buddi/gateway/dist/plugins/stage.js.map +1 -1
  70. package/node_modules/@buddi/gateway/dist/serve.js +1 -1
  71. package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
  72. package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts +1 -1
  73. package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js +1 -1
  74. package/node_modules/@buddi/gateway/dist/system-context.d.ts +11 -0
  75. package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
  76. package/node_modules/@buddi/gateway/dist/system-context.js +42 -1
  77. package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
  78. package/node_modules/@buddi/gateway/dist/telegram/approvals.js +1 -1
  79. package/node_modules/@buddi/gateway/dist/telegram/approvals.js.map +1 -1
  80. package/node_modules/@buddi/gateway/dist/telegram/browser-view.js +1 -1
  81. package/node_modules/@buddi/gateway/dist/telegram/browser-view.js.map +1 -1
  82. package/node_modules/@buddi/gateway/dist/web/api-routes.js +6 -6
  83. package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
  84. package/node_modules/@buddi/gateway/dist/web/approval-ask.js +1 -1
  85. package/node_modules/@buddi/gateway/dist/web/extension.d.ts +6 -0
  86. package/node_modules/@buddi/gateway/dist/web/extension.d.ts.map +1 -1
  87. package/node_modules/@buddi/gateway/dist/web/extension.js +22 -11
  88. package/node_modules/@buddi/gateway/dist/web/extension.js.map +1 -1
  89. package/node_modules/@buddi/gateway/dist/web/read.d.ts +1 -1
  90. package/node_modules/@buddi/gateway/dist/web/read.d.ts.map +1 -1
  91. package/node_modules/@buddi/gateway/dist/web/server.js +4 -4
  92. package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
  93. package/node_modules/@buddi/gateway/dist/web/service.d.ts +6 -1
  94. package/node_modules/@buddi/gateway/dist/web/service.d.ts.map +1 -1
  95. package/node_modules/@buddi/gateway/dist/web/service.js +10 -1
  96. package/node_modules/@buddi/gateway/dist/web/service.js.map +1 -1
  97. package/node_modules/@buddi/gateway/dist/web/skills.d.ts.map +1 -1
  98. package/node_modules/@buddi/gateway/dist/web/skills.js +2 -1
  99. package/node_modules/@buddi/gateway/dist/web/skills.js.map +1 -1
  100. package/node_modules/@buddi/gateway/dist/web/write.d.ts +1 -1
  101. package/node_modules/@buddi/gateway/dist/web/write.js +1 -1
  102. package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
  103. package/node_modules/@buddi/install/dist/app-layout.d.ts +53 -0
  104. package/node_modules/@buddi/install/dist/app-layout.d.ts.map +1 -1
  105. package/node_modules/@buddi/install/dist/app-layout.js +123 -10
  106. package/node_modules/@buddi/install/dist/app-layout.js.map +1 -1
  107. package/node_modules/@buddi/install/dist/cloudflared.js +2 -2
  108. package/node_modules/@buddi/install/dist/cloudflared.js.map +1 -1
  109. package/node_modules/@buddi/install/dist/environment.d.ts +40 -1
  110. package/node_modules/@buddi/install/dist/environment.d.ts.map +1 -1
  111. package/node_modules/@buddi/install/dist/environment.js +158 -12
  112. package/node_modules/@buddi/install/dist/environment.js.map +1 -1
  113. package/node_modules/@buddi/install/dist/launcher.d.ts.map +1 -1
  114. package/node_modules/@buddi/install/dist/launcher.js +340 -54
  115. package/node_modules/@buddi/install/dist/launcher.js.map +1 -1
  116. package/node_modules/@buddi/install/dist/linux-install.d.ts +41 -0
  117. package/node_modules/@buddi/install/dist/linux-install.d.ts.map +1 -0
  118. package/node_modules/@buddi/install/dist/linux-install.js +86 -0
  119. package/node_modules/@buddi/install/dist/linux-install.js.map +1 -0
  120. package/node_modules/@buddi/install/dist/postgres-check.js +1 -1
  121. package/node_modules/@buddi/install/dist/postgres-check.js.map +1 -1
  122. package/node_modules/@buddi/install/dist/product-uninstall.d.ts +14 -0
  123. package/node_modules/@buddi/install/dist/product-uninstall.d.ts.map +1 -1
  124. package/node_modules/@buddi/install/dist/product-uninstall.js +10 -0
  125. package/node_modules/@buddi/install/dist/product-uninstall.js.map +1 -1
  126. package/node_modules/@buddi/install/dist/runtime-info.d.ts +23 -0
  127. package/node_modules/@buddi/install/dist/runtime-info.d.ts.map +1 -0
  128. package/node_modules/@buddi/install/dist/runtime-info.js +72 -0
  129. package/node_modules/@buddi/install/dist/runtime-info.js.map +1 -0
  130. package/node_modules/@buddi/install/dist/supervisor.d.ts +60 -3
  131. package/node_modules/@buddi/install/dist/supervisor.d.ts.map +1 -1
  132. package/node_modules/@buddi/install/dist/supervisor.js +175 -17
  133. package/node_modules/@buddi/install/dist/supervisor.js.map +1 -1
  134. package/node_modules/@buddi/install/dist/uninstall.d.ts +49 -3
  135. package/node_modules/@buddi/install/dist/uninstall.d.ts.map +1 -1
  136. package/node_modules/@buddi/install/dist/uninstall.js +184 -27
  137. package/node_modules/@buddi/install/dist/uninstall.js.map +1 -1
  138. package/node_modules/@buddi/install/dist/upgrade.d.ts +20 -5
  139. package/node_modules/@buddi/install/dist/upgrade.d.ts.map +1 -1
  140. package/node_modules/@buddi/install/dist/upgrade.js +125 -62
  141. package/node_modules/@buddi/install/dist/upgrade.js.map +1 -1
  142. package/node_modules/@buddi/install/dist/windows-install.d.ts +102 -0
  143. package/node_modules/@buddi/install/dist/windows-install.d.ts.map +1 -0
  144. package/node_modules/@buddi/install/dist/windows-install.js +223 -0
  145. package/node_modules/@buddi/install/dist/windows-install.js.map +1 -0
  146. package/node_modules/@buddi/install/dist/windows-setup.d.ts +107 -0
  147. package/node_modules/@buddi/install/dist/windows-setup.d.ts.map +1 -0
  148. package/node_modules/@buddi/install/dist/windows-setup.js +700 -0
  149. package/node_modules/@buddi/install/dist/windows-setup.js.map +1 -0
  150. package/node_modules/@buddi/install/dist/windows-task.d.ts +49 -0
  151. package/node_modules/@buddi/install/dist/windows-task.d.ts.map +1 -0
  152. package/node_modules/@buddi/install/dist/windows-task.js +167 -0
  153. package/node_modules/@buddi/install/dist/windows-task.js.map +1 -0
  154. package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
  155. package/node_modules/@buddi/runtime/dist/codex-direct.d.ts +1 -1
  156. package/node_modules/@buddi/runtime/dist/codex-direct.js +1 -1
  157. package/node_modules/@buddi/runtime/dist/openai.d.ts +11 -0
  158. package/node_modules/@buddi/runtime/dist/openai.d.ts.map +1 -1
  159. package/node_modules/@buddi/runtime/dist/openai.js +36 -3
  160. package/node_modules/@buddi/runtime/dist/openai.js.map +1 -1
  161. package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
  162. package/node_modules/@buddi/tool-artifacts/dist/tools/write.js +3 -3
  163. package/node_modules/@buddi/tool-artifacts/dist/tools/write.js.map +1 -1
  164. package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
  165. package/node_modules/@buddi/tool-browser/dist/availability.d.ts.map +1 -1
  166. package/node_modules/@buddi/tool-browser/dist/availability.js +1 -0
  167. package/node_modules/@buddi/tool-browser/dist/availability.js.map +1 -1
  168. package/node_modules/@buddi/tool-browser/dist/brand.d.ts +19 -0
  169. package/node_modules/@buddi/tool-browser/dist/brand.d.ts.map +1 -0
  170. package/node_modules/@buddi/tool-browser/dist/brand.js +31 -0
  171. package/node_modules/@buddi/tool-browser/dist/brand.js.map +1 -0
  172. package/node_modules/@buddi/tool-browser/dist/controller.d.ts +2 -2
  173. package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
  174. package/node_modules/@buddi/tool-browser/dist/controller.js +16 -7
  175. package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
  176. package/node_modules/@buddi/tool-browser/dist/downloads.js +1 -1
  177. package/node_modules/@buddi/tool-browser/dist/downloads.js.map +1 -1
  178. package/node_modules/@buddi/tool-browser/dist/extension.d.ts +3 -1
  179. package/node_modules/@buddi/tool-browser/dist/extension.d.ts.map +1 -1
  180. package/node_modules/@buddi/tool-browser/dist/extension.js +4 -4
  181. package/node_modules/@buddi/tool-browser/dist/extension.js.map +1 -1
  182. package/node_modules/@buddi/tool-browser/dist/index.d.ts +3 -2
  183. package/node_modules/@buddi/tool-browser/dist/index.d.ts.map +1 -1
  184. package/node_modules/@buddi/tool-browser/dist/index.js +7 -6
  185. package/node_modules/@buddi/tool-browser/dist/index.js.map +1 -1
  186. package/node_modules/@buddi/tool-browser/dist/routes.d.ts +12 -1
  187. package/node_modules/@buddi/tool-browser/dist/routes.d.ts.map +1 -1
  188. package/node_modules/@buddi/tool-browser/dist/routes.js +31 -14
  189. package/node_modules/@buddi/tool-browser/dist/routes.js.map +1 -1
  190. package/node_modules/@buddi/tool-browser/dist/service.d.ts +2 -0
  191. package/node_modules/@buddi/tool-browser/dist/service.d.ts.map +1 -1
  192. package/node_modules/@buddi/tool-browser/dist/service.js +6 -6
  193. package/node_modules/@buddi/tool-browser/dist/service.js.map +1 -1
  194. package/node_modules/@buddi/tool-browser/dist/telemetry.d.ts +2 -2
  195. package/node_modules/@buddi/tool-browser/dist/telemetry.js +2 -2
  196. package/node_modules/@buddi/tool-browser/dist/telemetry.js.map +1 -1
  197. package/node_modules/@buddi/tool-browser/dist/types.js +1 -1
  198. package/node_modules/@buddi/tool-browser/dist/types.js.map +1 -1
  199. package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
  200. package/node_modules/@buddi/tool-host/dist/index.d.ts +2 -1
  201. package/node_modules/@buddi/tool-host/dist/index.d.ts.map +1 -1
  202. package/node_modules/@buddi/tool-host/dist/index.js +11 -2
  203. package/node_modules/@buddi/tool-host/dist/index.js.map +1 -1
  204. package/node_modules/@buddi/tool-host/dist/process.d.ts +58 -1
  205. package/node_modules/@buddi/tool-host/dist/process.d.ts.map +1 -1
  206. package/node_modules/@buddi/tool-host/dist/process.js +229 -15
  207. package/node_modules/@buddi/tool-host/dist/process.js.map +1 -1
  208. package/node_modules/@buddi/tool-host/dist/service.d.ts +2 -0
  209. package/node_modules/@buddi/tool-host/dist/service.d.ts.map +1 -1
  210. package/node_modules/@buddi/tool-host/dist/service.js +8 -6
  211. package/node_modules/@buddi/tool-host/dist/service.js.map +1 -1
  212. package/node_modules/@buddi/tool-host/dist/skill-run.d.ts +10 -0
  213. package/node_modules/@buddi/tool-host/dist/skill-run.d.ts.map +1 -1
  214. package/node_modules/@buddi/tool-host/dist/skill-run.js +14 -0
  215. package/node_modules/@buddi/tool-host/dist/skill-run.js.map +1 -1
  216. package/node_modules/@hono/node-server/package.json +2 -2
  217. package/node_modules/@types/node/README.md +1 -1
  218. package/node_modules/@types/node/package.json +2 -2
  219. package/node_modules/@types/node/util.d.ts +6 -3
  220. package/node_modules/content-disposition/README.md +105 -35
  221. package/node_modules/content-disposition/dist/index.d.ts +72 -0
  222. package/node_modules/content-disposition/dist/index.js +388 -0
  223. package/node_modules/content-disposition/dist/index.js.map +1 -0
  224. package/node_modules/content-disposition/package.json +31 -19
  225. package/node_modules/docx/dist/index.cjs +182 -80
  226. package/node_modules/docx/dist/index.d.cts +63 -6
  227. package/node_modules/docx/dist/index.d.ts +63 -6
  228. package/node_modules/docx/dist/index.iife.js +182 -80
  229. package/node_modules/docx/dist/index.mjs +182 -80
  230. package/node_modules/docx/dist/index.umd.cjs +182 -80
  231. package/node_modules/docx/dist/layout.cjs +1 -6
  232. package/node_modules/docx/dist/layout.iife.js +1 -6
  233. package/node_modules/docx/dist/layout.mjs +1 -6
  234. package/node_modules/docx/dist/layout.umd.cjs +1 -6
  235. package/node_modules/docx/package.json +4 -3
  236. package/node_modules/express/Readme.md +15 -9
  237. package/node_modules/express/lib/application.js +2 -2
  238. package/node_modules/express/lib/request.js +32 -19
  239. package/node_modules/express/lib/response.js +27 -30
  240. package/node_modules/express/node_modules/content-type/LICENSE +22 -0
  241. package/node_modules/express/node_modules/content-type/README.md +71 -0
  242. package/node_modules/express/node_modules/content-type/dist/index.d.ts +46 -0
  243. package/node_modules/express/node_modules/content-type/dist/index.js +176 -0
  244. package/node_modules/express/node_modules/content-type/dist/index.js.map +1 -0
  245. package/node_modules/express/node_modules/content-type/package.json +52 -0
  246. package/node_modules/express/package.json +10 -10
  247. package/node_modules/imapflow/CHANGELOG.md +33 -0
  248. package/node_modules/imapflow/dist/cjs/commands/append.d.ts +1 -1
  249. package/node_modules/imapflow/dist/cjs/commands/append.js +15 -4
  250. package/node_modules/imapflow/dist/cjs/commands/compress.js +2 -2
  251. package/node_modules/imapflow/dist/cjs/commands/id.js +5 -3
  252. package/node_modules/imapflow/dist/cjs/commands/idle.js +9 -9
  253. package/node_modules/imapflow/dist/cjs/commands/list.js +2 -2
  254. package/node_modules/imapflow/dist/cjs/commands/namespace.js +18 -14
  255. package/node_modules/imapflow/dist/cjs/commands/quota.js +2 -3
  256. package/node_modules/imapflow/dist/cjs/commands/status.js +2 -4
  257. package/node_modules/imapflow/dist/cjs/connection-deadline.d.ts +1 -1
  258. package/node_modules/imapflow/dist/cjs/connection-deadline.js +2 -4
  259. package/node_modules/imapflow/dist/cjs/download.js +66 -35
  260. package/node_modules/imapflow/dist/cjs/errors.d.ts +15 -0
  261. package/node_modules/imapflow/dist/cjs/errors.js +22 -0
  262. package/node_modules/imapflow/dist/cjs/handler/imap-compiler.d.ts +4 -4
  263. package/node_modules/imapflow/dist/cjs/handler/imap-compiler.js +18 -18
  264. package/node_modules/imapflow/dist/cjs/handler/imap-parser.js +28 -3
  265. package/node_modules/imapflow/dist/cjs/handler/imap-stream.js +9 -8
  266. package/node_modules/imapflow/dist/cjs/handler/limits.d.ts +1 -1
  267. package/node_modules/imapflow/dist/cjs/handler/limits.js +5 -7
  268. package/node_modules/imapflow/dist/cjs/handler/parser-instance.js +23 -38
  269. package/node_modules/imapflow/dist/cjs/handler/token-parser.d.ts +12 -0
  270. package/node_modules/imapflow/dist/cjs/handler/token-parser.js +44 -104
  271. package/node_modules/imapflow/dist/cjs/imap-flow.d.ts +4 -3
  272. package/node_modules/imapflow/dist/cjs/imap-flow.js +98 -72
  273. package/node_modules/imapflow/dist/cjs/package-info.d.ts +1 -1
  274. package/node_modules/imapflow/dist/cjs/package-info.js +1 -1
  275. package/node_modules/imapflow/dist/cjs/proxy-connection.js +2 -5
  276. package/node_modules/imapflow/dist/cjs/search-compiler.js +2 -3
  277. package/node_modules/imapflow/dist/cjs/tools.d.ts +14 -3
  278. package/node_modules/imapflow/dist/cjs/tools.js +30 -18
  279. package/node_modules/imapflow/dist/cjs/types.d.ts +11 -0
  280. package/node_modules/imapflow/dist/esm/commands/append.d.ts +1 -1
  281. package/node_modules/imapflow/dist/esm/commands/append.js +15 -4
  282. package/node_modules/imapflow/dist/esm/commands/compress.js +2 -2
  283. package/node_modules/imapflow/dist/esm/commands/id.js +6 -4
  284. package/node_modules/imapflow/dist/esm/commands/idle.js +9 -9
  285. package/node_modules/imapflow/dist/esm/commands/list.js +3 -3
  286. package/node_modules/imapflow/dist/esm/commands/namespace.js +19 -15
  287. package/node_modules/imapflow/dist/esm/commands/quota.js +3 -4
  288. package/node_modules/imapflow/dist/esm/commands/status.js +2 -4
  289. package/node_modules/imapflow/dist/esm/connection-deadline.d.ts +1 -1
  290. package/node_modules/imapflow/dist/esm/connection-deadline.js +2 -4
  291. package/node_modules/imapflow/dist/esm/download.js +66 -35
  292. package/node_modules/imapflow/dist/esm/errors.d.ts +15 -0
  293. package/node_modules/imapflow/dist/esm/errors.js +21 -0
  294. package/node_modules/imapflow/dist/esm/handler/imap-compiler.d.ts +4 -4
  295. package/node_modules/imapflow/dist/esm/handler/imap-compiler.js +18 -18
  296. package/node_modules/imapflow/dist/esm/handler/imap-parser.js +28 -3
  297. package/node_modules/imapflow/dist/esm/handler/imap-stream.js +9 -8
  298. package/node_modules/imapflow/dist/esm/handler/limits.d.ts +1 -1
  299. package/node_modules/imapflow/dist/esm/handler/limits.js +5 -7
  300. package/node_modules/imapflow/dist/esm/handler/parser-instance.js +23 -38
  301. package/node_modules/imapflow/dist/esm/handler/token-parser.d.ts +12 -0
  302. package/node_modules/imapflow/dist/esm/handler/token-parser.js +44 -104
  303. package/node_modules/imapflow/dist/esm/imap-flow.d.ts +4 -3
  304. package/node_modules/imapflow/dist/esm/imap-flow.js +99 -73
  305. package/node_modules/imapflow/dist/esm/package-info.d.ts +1 -1
  306. package/node_modules/imapflow/dist/esm/package-info.js +1 -1
  307. package/node_modules/imapflow/dist/esm/proxy-connection.js +2 -5
  308. package/node_modules/imapflow/dist/esm/search-compiler.js +2 -3
  309. package/node_modules/imapflow/dist/esm/tools.d.ts +14 -3
  310. package/node_modules/imapflow/dist/esm/tools.js +30 -19
  311. package/node_modules/imapflow/dist/esm/types.d.ts +11 -0
  312. package/node_modules/imapflow/package.json +6 -3
  313. package/node_modules/ip-address/README.md +70 -70
  314. package/node_modules/ip-address/dist/ipv6.js +7 -4
  315. package/node_modules/ip-address/dist/ipv6.js.map +1 -1
  316. package/node_modules/ip-address/dist/v6/constants.d.ts +3 -0
  317. package/node_modules/ip-address/dist/v6/constants.js +3 -0
  318. package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
  319. package/node_modules/ip-address/package.json +2 -1
  320. package/node_modules/marked/bin/main.js +1 -1
  321. package/node_modules/marked/lib/marked.d.ts +6 -3
  322. package/node_modules/marked/lib/marked.esm.js +48 -50
  323. package/node_modules/marked/lib/marked.esm.js.map +3 -3
  324. package/node_modules/marked/lib/marked.umd.js +45 -47
  325. package/node_modules/marked/lib/marked.umd.js.map +3 -3
  326. package/node_modules/marked/man/marked.1 +1 -1
  327. package/node_modules/marked/package.json +1 -1
  328. package/node_modules/process-warning/.github/workflows/ci.yml +1 -1
  329. package/node_modules/process-warning/.github/workflows/lock-threads.yml +1 -1
  330. package/node_modules/process-warning/.github/workflows/release.yml +24 -0
  331. package/node_modules/process-warning/README.md +46 -46
  332. package/node_modules/process-warning/package.json +1 -1
  333. package/package.json +2 -2
  334. package/packages/cli/dist/.tsbuildinfo +1 -1
  335. package/packages/cli/dist/dashboard-cmd.d.ts.map +1 -1
  336. package/packages/cli/dist/dashboard-cmd.js +6 -3
  337. package/packages/cli/dist/dashboard-cmd.js.map +1 -1
  338. package/packages/cli/dist/main.js +2 -2
  339. package/packages/cli/dist/main.js.map +1 -1
  340. package/packages/cli/dist/status.d.ts +16 -2
  341. package/packages/cli/dist/status.d.ts.map +1 -1
  342. package/packages/cli/dist/status.js +42 -2
  343. package/packages/cli/dist/status.js.map +1 -1
  344. package/packages/core/dist/.tsbuildinfo +1 -1
  345. package/packages/core/dist/agents/catalog.d.ts +6 -0
  346. package/packages/core/dist/agents/catalog.d.ts.map +1 -1
  347. package/packages/core/dist/agents/catalog.js +1 -1
  348. package/packages/core/dist/agents/catalog.js.map +1 -1
  349. package/packages/core/dist/backup/archive.d.ts +6 -0
  350. package/packages/core/dist/backup/archive.d.ts.map +1 -1
  351. package/packages/core/dist/backup/archive.js +19 -6
  352. package/packages/core/dist/backup/archive.js.map +1 -1
  353. package/packages/core/dist/postgres/binaries.d.ts +21 -1
  354. package/packages/core/dist/postgres/binaries.d.ts.map +1 -1
  355. package/packages/core/dist/postgres/binaries.js +72 -10
  356. package/packages/core/dist/postgres/binaries.js.map +1 -1
  357. package/packages/core/dist/postgres/cluster.d.ts +8 -0
  358. package/packages/core/dist/postgres/cluster.d.ts.map +1 -1
  359. package/packages/core/dist/postgres/cluster.js +119 -17
  360. package/packages/core/dist/postgres/cluster.js.map +1 -1
  361. package/packages/core/dist/postgres/windows-guard.d.ts +20 -0
  362. package/packages/core/dist/postgres/windows-guard.d.ts.map +1 -0
  363. package/packages/core/dist/postgres/windows-guard.js +140 -0
  364. package/packages/core/dist/postgres/windows-guard.js.map +1 -0
  365. package/packages/gateway/dist/.tsbuildinfo +1 -1
  366. package/packages/gateway/dist/agents/catalog.d.ts.map +1 -1
  367. package/packages/gateway/dist/agents/catalog.js +3 -2
  368. package/packages/gateway/dist/agents/catalog.js.map +1 -1
  369. package/packages/gateway/dist/agents/catalogue-package.d.ts +2 -2
  370. package/packages/gateway/dist/agents/catalogue-package.d.ts.map +1 -1
  371. package/packages/gateway/dist/agents/catalogue-package.js +1 -1
  372. package/packages/gateway/dist/agents/catalogue-package.js.map +1 -1
  373. package/packages/gateway/dist/agents/platform-catalogue.d.ts +6 -6
  374. package/packages/gateway/dist/agents/platform-catalogue.d.ts.map +1 -1
  375. package/packages/gateway/dist/agents/platform-catalogue.js +5 -5
  376. package/packages/gateway/dist/agents/platform-catalogue.js.map +1 -1
  377. package/packages/gateway/dist/browser-host.js +1 -1
  378. package/packages/gateway/dist/browser-host.js.map +1 -1
  379. package/packages/gateway/dist/missions/chrome-scope.d.ts +10 -10
  380. package/packages/gateway/dist/missions/chrome-scope.d.ts.map +1 -1
  381. package/packages/gateway/dist/missions/chrome-scope.js +20 -20
  382. package/packages/gateway/dist/missions/chrome-scope.js.map +1 -1
  383. package/packages/gateway/dist/missions/execute.d.ts +2 -2
  384. package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
  385. package/packages/gateway/dist/missions/execute.js +11 -11
  386. package/packages/gateway/dist/missions/execute.js.map +1 -1
  387. package/packages/gateway/dist/missions/reminders.d.ts +2 -2
  388. package/packages/gateway/dist/missions/reminders.d.ts.map +1 -1
  389. package/packages/gateway/dist/missions/reminders.js +5 -5
  390. package/packages/gateway/dist/missions/reminders.js.map +1 -1
  391. package/packages/gateway/dist/owner-notify.js +1 -1
  392. package/packages/gateway/dist/owner-notify.js.map +1 -1
  393. package/packages/gateway/dist/plugins/npm.d.ts +9 -2
  394. package/packages/gateway/dist/plugins/npm.d.ts.map +1 -1
  395. package/packages/gateway/dist/plugins/npm.js +29 -6
  396. package/packages/gateway/dist/plugins/npm.js.map +1 -1
  397. package/packages/gateway/dist/plugins/stage.d.ts.map +1 -1
  398. package/packages/gateway/dist/plugins/stage.js +2 -2
  399. package/packages/gateway/dist/plugins/stage.js.map +1 -1
  400. package/packages/gateway/dist/serve.js +1 -1
  401. package/packages/gateway/dist/serve.js.map +1 -1
  402. package/packages/gateway/dist/surfaces/browser-cards.d.ts +1 -1
  403. package/packages/gateway/dist/surfaces/browser-cards.js +1 -1
  404. package/packages/gateway/dist/system-context.d.ts +11 -0
  405. package/packages/gateway/dist/system-context.d.ts.map +1 -1
  406. package/packages/gateway/dist/system-context.js +42 -1
  407. package/packages/gateway/dist/system-context.js.map +1 -1
  408. package/packages/gateway/dist/telegram/approvals.js +1 -1
  409. package/packages/gateway/dist/telegram/approvals.js.map +1 -1
  410. package/packages/gateway/dist/telegram/browser-view.js +1 -1
  411. package/packages/gateway/dist/telegram/browser-view.js.map +1 -1
  412. package/packages/gateway/dist/web/api-routes.js +6 -6
  413. package/packages/gateway/dist/web/api-routes.js.map +1 -1
  414. package/packages/gateway/dist/web/approval-ask.js +1 -1
  415. package/packages/gateway/dist/web/extension.d.ts +6 -0
  416. package/packages/gateway/dist/web/extension.d.ts.map +1 -1
  417. package/packages/gateway/dist/web/extension.js +22 -11
  418. package/packages/gateway/dist/web/extension.js.map +1 -1
  419. package/packages/gateway/dist/web/read.d.ts +1 -1
  420. package/packages/gateway/dist/web/read.d.ts.map +1 -1
  421. package/packages/gateway/dist/web/server.js +4 -4
  422. package/packages/gateway/dist/web/server.js.map +1 -1
  423. package/packages/gateway/dist/web/service.d.ts +6 -1
  424. package/packages/gateway/dist/web/service.d.ts.map +1 -1
  425. package/packages/gateway/dist/web/service.js +10 -1
  426. package/packages/gateway/dist/web/service.js.map +1 -1
  427. package/packages/gateway/dist/web/skills.d.ts.map +1 -1
  428. package/packages/gateway/dist/web/skills.js +2 -1
  429. package/packages/gateway/dist/web/skills.js.map +1 -1
  430. package/packages/gateway/dist/web/write.d.ts +1 -1
  431. package/packages/gateway/dist/web/write.js +1 -1
  432. package/packages/install/dist/.tsbuildinfo +1 -1
  433. package/packages/install/dist/app-layout.d.ts +53 -0
  434. package/packages/install/dist/app-layout.d.ts.map +1 -1
  435. package/packages/install/dist/app-layout.js +123 -10
  436. package/packages/install/dist/app-layout.js.map +1 -1
  437. package/packages/install/dist/cloudflared.js +2 -2
  438. package/packages/install/dist/cloudflared.js.map +1 -1
  439. package/packages/install/dist/environment.d.ts +40 -1
  440. package/packages/install/dist/environment.d.ts.map +1 -1
  441. package/packages/install/dist/environment.js +158 -12
  442. package/packages/install/dist/environment.js.map +1 -1
  443. package/packages/install/dist/launcher.d.ts.map +1 -1
  444. package/packages/install/dist/launcher.js +340 -54
  445. package/packages/install/dist/launcher.js.map +1 -1
  446. package/packages/install/dist/linux-install.d.ts +41 -0
  447. package/packages/install/dist/linux-install.d.ts.map +1 -0
  448. package/packages/install/dist/linux-install.js +86 -0
  449. package/packages/install/dist/linux-install.js.map +1 -0
  450. package/packages/install/dist/postgres-check.js +1 -1
  451. package/packages/install/dist/postgres-check.js.map +1 -1
  452. package/packages/install/dist/product-uninstall.d.ts +14 -0
  453. package/packages/install/dist/product-uninstall.d.ts.map +1 -1
  454. package/packages/install/dist/product-uninstall.js +10 -0
  455. package/packages/install/dist/product-uninstall.js.map +1 -1
  456. package/packages/install/dist/runtime-info.d.ts +23 -0
  457. package/packages/install/dist/runtime-info.d.ts.map +1 -0
  458. package/packages/install/dist/runtime-info.js +72 -0
  459. package/packages/install/dist/runtime-info.js.map +1 -0
  460. package/packages/install/dist/supervisor.d.ts +60 -3
  461. package/packages/install/dist/supervisor.d.ts.map +1 -1
  462. package/packages/install/dist/supervisor.js +175 -17
  463. package/packages/install/dist/supervisor.js.map +1 -1
  464. package/packages/install/dist/uninstall.d.ts +49 -3
  465. package/packages/install/dist/uninstall.d.ts.map +1 -1
  466. package/packages/install/dist/uninstall.js +184 -27
  467. package/packages/install/dist/uninstall.js.map +1 -1
  468. package/packages/install/dist/upgrade.d.ts +20 -5
  469. package/packages/install/dist/upgrade.d.ts.map +1 -1
  470. package/packages/install/dist/upgrade.js +125 -62
  471. package/packages/install/dist/upgrade.js.map +1 -1
  472. package/packages/install/dist/windows-install.d.ts +102 -0
  473. package/packages/install/dist/windows-install.d.ts.map +1 -0
  474. package/packages/install/dist/windows-install.js +223 -0
  475. package/packages/install/dist/windows-install.js.map +1 -0
  476. package/packages/install/dist/windows-setup.d.ts +107 -0
  477. package/packages/install/dist/windows-setup.d.ts.map +1 -0
  478. package/packages/install/dist/windows-setup.js +700 -0
  479. package/packages/install/dist/windows-setup.js.map +1 -0
  480. package/packages/install/dist/windows-task.d.ts +49 -0
  481. package/packages/install/dist/windows-task.d.ts.map +1 -0
  482. package/packages/install/dist/windows-task.js +167 -0
  483. package/packages/install/dist/windows-task.js.map +1 -0
  484. package/packages/runtime/dist/.tsbuildinfo +1 -1
  485. package/packages/runtime/dist/codex-direct.d.ts +1 -1
  486. package/packages/runtime/dist/codex-direct.js +1 -1
  487. package/packages/runtime/dist/openai.d.ts +11 -0
  488. package/packages/runtime/dist/openai.d.ts.map +1 -1
  489. package/packages/runtime/dist/openai.js +36 -3
  490. package/packages/runtime/dist/openai.js.map +1 -1
  491. package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
  492. package/packages/tools/artifacts/dist/tools/write.js +3 -3
  493. package/packages/tools/artifacts/dist/tools/write.js.map +1 -1
  494. package/packages/tools/browser/dist/.tsbuildinfo +1 -1
  495. package/packages/tools/browser/dist/availability.d.ts.map +1 -1
  496. package/packages/tools/browser/dist/availability.js +1 -0
  497. package/packages/tools/browser/dist/availability.js.map +1 -1
  498. package/packages/tools/browser/dist/brand.d.ts +19 -0
  499. package/packages/tools/browser/dist/brand.d.ts.map +1 -0
  500. package/packages/tools/browser/dist/brand.js +31 -0
  501. package/packages/tools/browser/dist/brand.js.map +1 -0
  502. package/packages/tools/browser/dist/controller.d.ts +2 -2
  503. package/packages/tools/browser/dist/controller.d.ts.map +1 -1
  504. package/packages/tools/browser/dist/controller.js +16 -7
  505. package/packages/tools/browser/dist/controller.js.map +1 -1
  506. package/packages/tools/browser/dist/downloads.js +1 -1
  507. package/packages/tools/browser/dist/downloads.js.map +1 -1
  508. package/packages/tools/browser/dist/extension.d.ts +3 -1
  509. package/packages/tools/browser/dist/extension.d.ts.map +1 -1
  510. package/packages/tools/browser/dist/extension.js +4 -4
  511. package/packages/tools/browser/dist/extension.js.map +1 -1
  512. package/packages/tools/browser/dist/index.d.ts +3 -2
  513. package/packages/tools/browser/dist/index.d.ts.map +1 -1
  514. package/packages/tools/browser/dist/index.js +7 -6
  515. package/packages/tools/browser/dist/index.js.map +1 -1
  516. package/packages/tools/browser/dist/routes.d.ts +12 -1
  517. package/packages/tools/browser/dist/routes.d.ts.map +1 -1
  518. package/packages/tools/browser/dist/routes.js +31 -14
  519. package/packages/tools/browser/dist/routes.js.map +1 -1
  520. package/packages/tools/browser/dist/service.d.ts +2 -0
  521. package/packages/tools/browser/dist/service.d.ts.map +1 -1
  522. package/packages/tools/browser/dist/service.js +6 -6
  523. package/packages/tools/browser/dist/service.js.map +1 -1
  524. package/packages/tools/browser/dist/telemetry.d.ts +2 -2
  525. package/packages/tools/browser/dist/telemetry.js +2 -2
  526. package/packages/tools/browser/dist/telemetry.js.map +1 -1
  527. package/packages/tools/browser/dist/types.js +1 -1
  528. package/packages/tools/browser/dist/types.js.map +1 -1
  529. package/packages/tools/host/dist/.tsbuildinfo +1 -1
  530. package/packages/tools/host/dist/index.d.ts +2 -1
  531. package/packages/tools/host/dist/index.d.ts.map +1 -1
  532. package/packages/tools/host/dist/index.js +11 -2
  533. package/packages/tools/host/dist/index.js.map +1 -1
  534. package/packages/tools/host/dist/process.d.ts +58 -1
  535. package/packages/tools/host/dist/process.d.ts.map +1 -1
  536. package/packages/tools/host/dist/process.js +229 -15
  537. package/packages/tools/host/dist/process.js.map +1 -1
  538. package/packages/tools/host/dist/service.d.ts +2 -0
  539. package/packages/tools/host/dist/service.d.ts.map +1 -1
  540. package/packages/tools/host/dist/service.js +8 -6
  541. package/packages/tools/host/dist/service.js.map +1 -1
  542. package/packages/tools/host/dist/skill-run.d.ts +10 -0
  543. package/packages/tools/host/dist/skill-run.d.ts.map +1 -1
  544. package/packages/tools/host/dist/skill-run.js +14 -0
  545. package/packages/tools/host/dist/skill-run.js.map +1 -1
  546. package/packages/web/dist/assets/index-DnZhfnM7.js +155 -0
  547. package/packages/web/dist/assets/{lottie_light-DROBTM6Y.js → lottie_light-CGUtDt_b.js} +1 -1
  548. package/packages/web/dist/build.json +1 -1
  549. package/packages/web/dist/index.html +1 -1
  550. package/packages/web/dist/precache.json +3 -3
  551. package/node_modules/content-disposition/index.js +0 -536
  552. package/packages/web/dist/assets/index-oxmxR39o.js +0 -155
@@ -9,19 +9,23 @@
9
9
  */
10
10
  import path from 'node:path';
11
11
  import { fileURLToPath } from 'node:url';
12
- import { spawn, execFile } from 'node:child_process';
12
+ import { spawn, execFile, execFileSync } from 'node:child_process';
13
13
  import { request } from 'node:http';
14
14
  import { open, mkdir, writeFile, rm, rename, copyFile, chmod } from 'node:fs/promises';
15
15
  import os from 'node:os';
16
16
  import { promisify } from 'node:util';
17
- import { existsSync, readFileSync, realpathSync } from 'node:fs';
18
- import { environment, identityMismatch, portMovedLines, dashboardReady, launchAgentLabel, launchAgentPlist, reloadLaunchAgent, nativeEnvironment, reloadSystemdUnit, systemdUnitPath, atomicJson, browsersDir, SERVICE_UNIT_VAR } from './environment.js';
19
- import { briefSupervisorEnv, supervise, supervisorSocket } from './supervisor.js';
17
+ import { existsSync, openSync, readFileSync, realpathSync, writeFileSync, writeSync } from 'node:fs';
18
+ import { environment, lockHolder, identityMismatch, portMovedLines, dashboardReady, launchAgentLabel, launchAgentPlist, reloadLaunchAgent, nativeEnvironment, reloadSystemdUnit, systemdUnitPath, atomicJson, browsersDir, SERVICE_UNIT_VAR } from './environment.js';
19
+ import { NotOurSupervisor, answeredBySupervisor, briefSupervisorEnv, runningOrStarting, supervise, supervisorSocket } from './supervisor.js';
20
20
  import { keptPluginDataLine, readKeptPluginData } from './kept-data.js';
21
21
  import { readProfileZone, timezoneLine } from './doctor-timezone.js';
22
22
  import { installedVersion, readUpgradeState, upgradeDoctorLines, versionView } from './upgrade.js';
23
- import { APP_RUNNING_LINE, appLayout, insideAppBundle, runsAppCopy } from './app-layout.js';
23
+ import { APP_RUNNING_LINE, appLayout, insideAppBundle, linuxInstall, runsAppCopy, windowsInstall } from './app-layout.js';
24
+ import { runtimeFacts, runtimeLines } from './runtime-info.js';
25
+ import { commandOwnedBy, desktopEntryPaths, linuxUnitSpec, ownDesktopEntries } from './linux-install.js';
24
26
  import { APP_BUNDLE_ID, SHIM_REFUSAL, SHIM_VAR, shimAction, shimDoctorLines, shimRefusesSupervise, shimsFor } from './cli-shim.js';
27
+ import { buildSuperviseScript, buildTaskXml, followLogsCommand, registerWindowsTask, taskXmlBytes, windowsTaskName, windowsTaskScript, windowsTaskXmlFile } from './windows-task.js';
28
+ import { SETUP_DATA_KEY, SETUP_UNINSTALL_VAR, cleanupNodeCopyCommand, regQueryValue, uninstallerIsOurs, insideFolder, readWindowsInstallerRecord, windowsCommandOwnedBy, windowsTaskSpec } from './windows-install.js';
25
29
  const entry = fileURLToPath(import.meta.url);
26
30
  // <root>/packages/install/dist/launcher.js — the installation root is three up.
27
31
  const root = path.resolve(path.dirname(entry), '../../..');
@@ -57,6 +61,11 @@ async function ask(ctx, method, route, body) {
57
61
  headers: { host: 'localhost', ...(payload === undefined ? {} : { 'content-type': 'application/json', 'content-length': Buffer.byteLength(payload) }) },
58
62
  timeout: 25_000,
59
63
  }, res => {
64
+ // Windows: a pipe's name can be listed by anyone; the secret beside it in the data directory cannot.
65
+ if (!answeredBySupervisor(ctx.data, res.headers)) {
66
+ res.resume();
67
+ return reject(new NotOurSupervisor());
68
+ }
60
69
  let text = '';
61
70
  res.setEncoding('utf8');
62
71
  res.on('data', chunk => { text += chunk; });
@@ -99,12 +108,75 @@ function isAppInstall(ctx) {
99
108
  function runsFromApp(status, ctx) {
100
109
  return runsAppCopy(status.installRoot, ctx.data);
101
110
  }
111
+ /**
112
+ * Is this the Linux install (scripts/install.sh)? Its `buddi` and its unit say
113
+ * so; a process they started with a trimmed environment (the uninstall the
114
+ * dashboard spawns) is told by the layout: on Linux there is no buddi.app, so
115
+ * a release under `<data>/releases` is the installer's.
116
+ */
117
+ function isLinuxInstall(ctx) {
118
+ return linuxInstall(process.env) || (process.platform === 'linux' && isAppInstall(ctx));
119
+ }
120
+ /**
121
+ * Is this the Windows install (the setup, apps/windows)? Its `buddi.cmd` and
122
+ * its task say so; as on Linux, there is no buddi.app on Windows, so a
123
+ * release under `<data>\releases` is the setup's.
124
+ */
125
+ function isWindowsInstall(ctx) {
126
+ return windowsInstall(process.env) || (process.platform === 'win32' && isAppInstall(ctx));
127
+ }
102
128
  function withApp(view, ctx) {
103
- return isAppInstall(ctx) ? { ...view, app: true } : view;
129
+ return isAppInstall(ctx) && !isLinuxInstall(ctx) && !isWindowsInstall(ctx) ? { ...view, app: true } : view;
104
130
  }
105
131
  async function control(ctx, action = 'status') {
106
132
  return await ask(ctx, action === 'status' ? 'GET' : 'POST', `/${action}`);
107
133
  }
134
+ /** The pid `supervisor.lock` names, while that process lives and the lock is of this boot (environment.ts `lockHolder`). */
135
+ function supervisorLockPid(data) {
136
+ return lockHolder(data);
137
+ }
138
+ /**
139
+ * Windows: a postmaster still running on this installation's cluster, its
140
+ * `postmaster.pid` naming a live process. There it can outlive its
141
+ * supervisor for a moment (it is stopped with pg_ctl), and a folder it holds cannot be removed.
142
+ * Elsewhere the supervisor's own exit is the answer, as before.
143
+ */
144
+ function postmasterLeft(data) {
145
+ if (process.platform !== 'win32')
146
+ return false;
147
+ let pid;
148
+ try {
149
+ pid = Number(readFileSync(path.join(data, 'postgres', 'postmaster.pid'), 'utf8').split('\n')[0].trim());
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ if (!Number.isInteger(pid) || pid <= 0)
155
+ return false;
156
+ try {
157
+ process.kill(pid, 0);
158
+ return true;
159
+ }
160
+ catch {
161
+ return false;
162
+ }
163
+ }
164
+ /**
165
+ * Windows: stop the supervisor the way a signal does elsewhere. A kill there
166
+ * is TerminateProcess, which skips the database's shutdown, so it is asked on
167
+ * its socket and followed until its lock is gone. A refusal (a restore or an
168
+ * upgrade under way) is thrown, never overridden with a kill.
169
+ */
170
+ async function exitSupervisor(ctx, timeoutMs = 90_000) {
171
+ if (supervisorLockPid(ctx.data) === undefined)
172
+ return;
173
+ await ask(ctx, 'POST', '/exit');
174
+ for (let waited = 0; supervisorLockPid(ctx.data) !== undefined; waited += 250) {
175
+ if (waited >= timeoutMs)
176
+ throw new Error(`the supervisor (pid ${supervisorLockPid(ctx.data)}) did not stop within ${Math.round(timeoutMs / 1000)} seconds`);
177
+ await new Promise(resolve => setTimeout(resolve, 250));
178
+ }
179
+ }
108
180
  /** The supervisor's status as the sentence `buddi service status` prints. */
109
181
  export function serviceLine(status) {
110
182
  const gateway = status.gateway === 'running'
@@ -172,7 +244,7 @@ async function startSupervisorBriefly(ctx, lockPid) {
172
244
  const log = await open(path.join(ctx.data, 'logs/supervisor.log'), 'a', 0o600);
173
245
  let child;
174
246
  try {
175
- child = spawn(process.execPath, [entry, 'supervise'], { detached: true, stdio: ['ignore', log.fd, log.fd], env: briefSupervisorEnv(ctx.env, process.pid, SHIM_VAR) });
247
+ child = spawn(process.execPath, [entry, 'supervise'], { detached: true, stdio: ['ignore', log.fd, log.fd], env: briefSupervisorEnv(ctx.env, process.pid, SHIM_VAR), windowsHide: true });
176
248
  await new Promise((resolve, reject) => { child.once('spawn', resolve); child.once('error', reject); });
177
249
  }
178
250
  finally {
@@ -199,10 +271,15 @@ async function startSupervisorBriefly(ctx, lockPid) {
199
271
  process.removeListener('SIGINT', onInterrupt);
200
272
  process.removeListener('SIGTERM', onInterrupt);
201
273
  if (!exited && child.pid !== undefined) {
202
- try {
203
- process.kill(child.pid, 'SIGTERM');
274
+ // Windows: SIGTERM is TerminateProcess, which would skip the database's shutdown.
275
+ if (process.platform === 'win32')
276
+ await ask(ctx, 'POST', '/exit').catch(() => { });
277
+ else {
278
+ try {
279
+ process.kill(child.pid, 'SIGTERM');
280
+ }
281
+ catch { /* gone */ }
204
282
  }
205
- catch { /* gone */ }
206
283
  }
207
284
  const alive = () => { if (exited || child.pid === undefined)
208
285
  return false; try {
@@ -212,7 +289,7 @@ async function startSupervisorBriefly(ctx, lockPid) {
212
289
  catch {
213
290
  return false;
214
291
  } };
215
- for (let waited = 0; lockPid() !== undefined || alive(); waited += 250) {
292
+ for (let waited = 0; lockPid() !== undefined || alive() || postmasterLeft(ctx.data); waited += 250) {
216
293
  if (waited >= 60_000)
217
294
  throw new Error(`the database started for the last backup did not stop within a minute (supervisor pid ${child.pid})`);
218
295
  await new Promise(resolve => setTimeout(resolve, 250));
@@ -233,6 +310,73 @@ async function startSupervisorBriefly(ctx, lockPid) {
233
310
  await new Promise(resolve => setTimeout(resolve, 500));
234
311
  }
235
312
  }
313
+ /**
314
+ * What the Linux install put where: `installer.json` (written by
315
+ * scripts/install.sh) names the command and whether it turned on lingering;
316
+ * the command is removed only while it still carries the installer's marker.
317
+ */
318
+ function linuxInstallParts(ctx, home) {
319
+ let recorded = {};
320
+ try {
321
+ recorded = JSON.parse(readFileSync(path.join(ctx.data, 'installer.json'), 'utf8'));
322
+ }
323
+ catch { /* an older install: the defaults */ }
324
+ const command = typeof recorded.command === 'string' && path.isAbsolute(recorded.command) ? recorded.command : path.join(home, '.local', 'bin', 'buddi');
325
+ // Ours only while it runs this data folder: another installation may have written the same bin folder since.
326
+ const owned = () => commandOwnedBy((() => { try {
327
+ return readFileSync(command, 'utf8');
328
+ }
329
+ catch {
330
+ return undefined;
331
+ } })(), ctx.data, realpathSync);
332
+ return {
333
+ runtime: path.join(ctx.data, 'node'),
334
+ releases: appLayout(process.env) ?? path.join(ctx.data, 'releases'),
335
+ ...(owned() ? { command, commandOwned: owned } : {}),
336
+ ...(recorded.linger === true ? { linger: true } : {}),
337
+ desktopEntries: ownDesktopEntries(desktopEntryPaths(process.env, home), ctx.data, file => { try {
338
+ return readFileSync(file, 'utf8');
339
+ }
340
+ catch {
341
+ return undefined;
342
+ } }),
343
+ };
344
+ }
345
+ /**
346
+ * What the Windows setup put where: `installer.json` (written by its
347
+ * windows-setup.ts) names `buddi.cmd` and the setup's uninstaller; the command
348
+ * is removed only while it still runs this data folder.
349
+ */
350
+ function windowsInstallParts(ctx) {
351
+ const recorded = readWindowsInstallerRecord((() => { try {
352
+ return readFileSync(path.join(ctx.data, 'installer.json'), 'utf8');
353
+ }
354
+ catch {
355
+ return undefined;
356
+ } })());
357
+ const command = recorded.command;
358
+ const owned = () => command !== undefined && windowsCommandOwnedBy((() => { try {
359
+ return readFileSync(command, 'utf8');
360
+ }
361
+ catch {
362
+ return undefined;
363
+ } })(), ctx.data, realpathSync);
364
+ // The setup's one registration serves one data folder: started for another, it would remove that one.
365
+ const registered = (() => { try {
366
+ return regQueryValue(execFileSync('reg.exe', ['query', SETUP_DATA_KEY, '/v', 'DataDir'], { encoding: 'utf8', windowsHide: true }), 'DataDir');
367
+ }
368
+ catch {
369
+ return undefined;
370
+ } })();
371
+ const uninstaller = recorded.uninstaller !== undefined && existsSync(recorded.uninstaller) && uninstallerIsOurs(registered, ctx.data) ? recorded.uninstaller : undefined;
372
+ return {
373
+ runtime: path.join(ctx.data, 'node'),
374
+ releases: appLayout(process.env) ?? path.join(ctx.data, 'releases'),
375
+ ...(command !== undefined && owned() ? { command, commandOwned: owned } : {}),
376
+ // Run from the setup's own uninstaller, which removes its entry itself afterwards.
377
+ ...(uninstaller !== undefined && (process.env[SETUP_UNINSTALL_VAR] ?? '').trim() !== '1' ? { uninstaller } : {}),
378
+ };
379
+ }
236
380
  /**
237
381
  * `buddi uninstall`, in a packaged installation. The order and the refusals
238
382
  * are in `uninstall.ts`; this wires them to the real machine: the supervisor's
@@ -252,24 +396,7 @@ async function uninstall(ctx, rest) {
252
396
  const { purgeKeychain, clearTelegramMenu } = await import('@buddi/core/uninstall');
253
397
  const { dashboardAppOwnedBy } = await import('@buddi/cli');
254
398
  const home = os.homedir();
255
- const lockPid = () => {
256
- let pid;
257
- try {
258
- pid = Number(readFileSync(path.join(ctx.data, 'supervisor.lock'), 'utf8').trim());
259
- }
260
- catch {
261
- return undefined;
262
- }
263
- if (!Number.isInteger(pid) || pid <= 0)
264
- return undefined;
265
- try {
266
- process.kill(pid, 0);
267
- return pid;
268
- }
269
- catch {
270
- return undefined;
271
- }
272
- };
399
+ const lockPid = () => supervisorLockPid(ctx.data);
273
400
  const service = ctx.env.BUDDI_VAULT_SERVICE ?? 'buddi';
274
401
  const vault = (() => { try {
275
402
  return core.createVault({ env: ctx.env });
@@ -280,10 +407,37 @@ async function uninstall(ctx, rest) {
280
407
  const stored = await vault?.get('TELEGRAM_BOT_TOKEN').catch(() => null) ?? null;
281
408
  const token = stored ?? (ctx.env.TELEGRAM_BOT_TOKEN?.startsWith('<') ? undefined : ctx.env.TELEGRAM_BOT_TOKEN?.trim() || undefined);
282
409
  const app = dashboardAppOwnedBy(path.join(root, 'packages/cli/dist/main.js'), home);
410
+ const linuxParts = isLinuxInstall(ctx) ? linuxInstallParts(ctx, home) : undefined;
411
+ const windowsParts = isWindowsInstall(ctx) ? windowsInstallParts(ctx) : undefined;
412
+ if (windowsParts !== undefined && insideFolder(process.execPath, ctx.data)) {
413
+ // buddi.cmd, the dashboard and the setup's uninstaller run a copy of node from TEMP for this.
414
+ console.error(`buddi: this node runs from inside ${ctx.data}, which Windows will not remove while it runs. Run buddi uninstall from a new Command Prompt (buddi.cmd runs it from a copy), or remove buddi in Settings → Apps. Nothing was removed.`);
415
+ return 1;
416
+ }
417
+ // The copy of node this runs from (see above) goes once it has exited.
418
+ if (process.platform === 'win32') {
419
+ const cleanup = cleanupNodeCopyCommand(process.execPath, ctx.env.SystemRoot ?? ctx.env.SYSTEMROOT ?? 'C:\\Windows');
420
+ if (cleanup !== undefined)
421
+ process.once('exit', () => { try {
422
+ writeFileSync(cleanup.script.file, cleanup.script.text);
423
+ spawn(cleanup.command, cleanup.args, { detached: true, stdio: 'ignore', windowsHide: true, env: { ...process.env, ...cleanup.env }, cwd: os.homedir() }).unref();
424
+ }
425
+ catch { /* TEMP is cleaned by Windows too */ } });
426
+ }
283
427
  return await uninstallPackaged(options, {
428
+ ...(linuxParts === undefined ? {} : { linuxInstall: linuxParts }),
429
+ ...(windowsParts === undefined ? {} : { windowsInstall: windowsParts }),
284
430
  data: ctx.data, home, platform: process.platform, env: ctx.env, uid: process.getuid?.() ?? 501,
285
431
  exists: existsSync,
286
- remove: file => rm(file, { recursive: true, force: true }),
432
+ launch: async (command, argv) => {
433
+ await new Promise((resolve, reject) => {
434
+ const child = spawn(command, argv, { detached: true, stdio: 'ignore', windowsHide: true, cwd: home });
435
+ child.once('error', reject);
436
+ child.once('spawn', () => { child.unref(); resolve(); });
437
+ });
438
+ },
439
+ // Retried: on Windows a process that just exited can hold a folder for a moment (EBUSY).
440
+ remove: file => rm(file, { recursive: true, force: true, maxRetries: 10, retryDelay: 250 }),
287
441
  move: async (from, to) => {
288
442
  await mkdir(path.dirname(to), { recursive: true, mode: 0o700 });
289
443
  try {
@@ -295,7 +449,7 @@ async function uninstall(ctx, rest) {
295
449
  }
296
450
  },
297
451
  exec: (command, argv) => new Promise(resolve => {
298
- execFile(command, argv, { env: { ...nativeEnvironment(ctx.env), ...systemdSession(ctx.env) } }, (error, stdout, stderr) => {
452
+ execFile(command, argv, { env: { ...nativeEnvironment(ctx.env), ...systemdSession(ctx.env) }, windowsHide: true }, (error, stdout, stderr) => {
299
453
  const code = error?.code;
300
454
  resolve({ code: error ? (typeof code === 'number' ? code : 1) : 0, stdout: String(stdout), stderr: error && typeof code !== 'number' ? error.message : String(stderr) });
301
455
  });
@@ -308,7 +462,7 @@ async function uninstall(ctx, rest) {
308
462
  },
309
463
  // Run by buddi.app itself (its uninstall route), the app is already on its way out: nothing to say about it.
310
464
  buddiApp: async () => {
311
- if (appLayout(process.env) !== undefined)
465
+ if (appLayout(process.env) !== undefined || isLinuxInstall(ctx) || isWindowsInstall(ctx))
312
466
  return undefined;
313
467
  const status = await control(ctx).catch(() => undefined);
314
468
  if (status !== undefined && runsFromApp(status, ctx))
@@ -331,10 +485,20 @@ async function uninstall(ctx, rest) {
331
485
  return existsSync(file) ? JSON.parse(readFileSync(file, 'utf8')) : undefined;
332
486
  },
333
487
  supervisorPid: lockPid,
334
- signal: (pid, signal) => { try {
335
- process.kill(pid, signal);
336
- }
337
- catch { /* gone already */ } },
488
+ // Windows: a kill is TerminateProcess, which would skip the database's
489
+ // shutdown; the supervisor is asked on its socket instead, and a refusal
490
+ // (a restore or an upgrade under way) stops the uninstall, not the supervisor.
491
+ signal: async (pid, signal) => {
492
+ if (process.platform === 'win32' && pid === lockPid()) {
493
+ await exitSupervisor(ctx);
494
+ return;
495
+ }
496
+ try {
497
+ process.kill(pid, signal);
498
+ }
499
+ catch { /* gone already */ }
500
+ },
501
+ postmasterLeft: () => postmasterLeft(ctx.data),
338
502
  ...(core.vaultSelection({ env: ctx.env }) === 'keychain' ? {
339
503
  keychain: {
340
504
  service,
@@ -624,11 +788,20 @@ async function launchService(ctx, temporary) {
624
788
  const unit = systemdUnitPath(ctx.data, ctx.env);
625
789
  const { buildSystemdUnit } = await import('@buddi/cli');
626
790
  await mkdir(path.dirname(unit), { recursive: true });
791
+ /*
792
+ * The Linux install runs `<data>/releases/current` with its bundled node,
793
+ * named through the link rather than resolved: an upgrade switches the
794
+ * link and systemd's restart runs the new release from the same unit.
795
+ */
796
+ const releases = isLinuxInstall(ctx) ? appLayout(process.env) ?? path.join(ctx.data, 'releases') : undefined;
797
+ const spec = releases === undefined
798
+ ? { nodePath: process.execPath, serveEntry: entry, environment: { BUDDI_DATA_DIR: ctx.data, [SERVICE_UNIT_VAR]: label, ...serviceEnvironment() }, path: [path.dirname(process.execPath), '/usr/local/bin', '/usr/bin', '/bin'].join(':') }
799
+ : linuxUnitSpec({ data: ctx.data, releases, label, exists: existsSync, extra: serviceEnvironment() });
627
800
  await writeFile(unit, buildSystemdUnit({
628
- label, nodePath: process.execPath, serveEntry: entry, args: ['supervise'],
629
- environment: { BUDDI_DATA_DIR: ctx.data, [SERVICE_UNIT_VAR]: label, ...serviceEnvironment() },
801
+ label, nodePath: spec.nodePath, serveEntry: spec.serveEntry, args: ['supervise'],
802
+ environment: spec.environment,
630
803
  workingDirectory: ctx.data,
631
- path: [path.dirname(process.execPath), '/usr/local/bin', '/usr/bin', '/bin'].join(':'),
804
+ path: spec.path,
632
805
  logFile: path.join(ctx.data, 'logs/supervisor.log'), errorFile: path.join(ctx.data, 'logs/supervisor.log'),
633
806
  }), { mode: 0o600 });
634
807
  try {
@@ -638,14 +811,58 @@ async function launchService(ctx, temporary) {
638
811
  const detail = error instanceof Error ? error.message : String(error);
639
812
  throw new Error(`systemd could not start the service (${detail.trim()}). The unit is at ${unit}. Run buddi --no-service to start it in the foreground instead.`);
640
813
  }
641
- console.log(`Background service: systemd user unit ${label} (survives logout only after: loginctl enable-linger ${ctx.env.USER ?? '$USER'})`);
814
+ // Lingering already on (the Linux installer turns it on when it may): nothing to add.
815
+ const lingering = await exec('loginctl', ['show-user', ctx.env.USER ?? os.userInfo().username, '-p', 'Linger', '--value'], { env: nativeEnvironment(ctx.env) })
816
+ .then(out => out.stdout.trim() === 'yes', () => false);
817
+ console.log(`Background service: systemd user unit ${label}${lingering ? '' : ` (survives logout only after: loginctl enable-linger ${ctx.env.USER ?? '$USER'})`}`);
818
+ return;
819
+ }
820
+ if (!temporary && process.platform === 'win32') {
821
+ /*
822
+ * A Task Scheduler task of the owner's (windows-task.ts): started now, and
823
+ * at every logon from then on. Its script carries what the plist's
824
+ * environment carries on a Mac.
825
+ */
826
+ const label = launchAgentLabel(ctx.data);
827
+ const script = windowsTaskScript(ctx.data);
828
+ await mkdir(path.dirname(script), { recursive: true, mode: 0o700 });
829
+ /*
830
+ * The Windows install runs `<data>\releases\current` with its bundled
831
+ * node, named through the junction: an upgrade switches it, and the task
832
+ * runs the new release at the next sign-in without being written again.
833
+ */
834
+ const logs = { [SUPERVISOR_LOG_VAR]: path.join(ctx.data, 'logs', 'supervisor.log') };
835
+ const spec = isWindowsInstall(ctx)
836
+ ? windowsTaskSpec({ data: ctx.data, label, exists: existsSync, extra: { ...logs, ...serviceEnvironment() } })
837
+ : { nodePath: process.execPath, entry, environment: { BUDDI_DATA_DIR: ctx.data, ...logs, ...serviceEnvironment() } };
838
+ await writeFile(script, buildSuperviseScript({
839
+ ...spec,
840
+ // What the supervisor says before it opens its log (a node that will not start).
841
+ logFile: path.join(ctx.data, 'logs', 'service.log'),
842
+ }), { mode: 0o600 });
843
+ const user = [ctx.env.USERDOMAIN, ctx.env.USERNAME ?? os.userInfo().username].filter(Boolean).join('\\');
844
+ await writeFile(windowsTaskXmlFile(ctx.data), taskXmlBytes(buildTaskXml({
845
+ // Not the data directory: Windows will not remove a folder a process runs in, and uninstall removes it.
846
+ user, script, workingDirectory: os.homedir(), systemRoot: ctx.env.SystemRoot ?? ctx.env.SYSTEMROOT ?? 'C:\\Windows',
847
+ })), { mode: 0o600 });
848
+ // A running supervisor stops on its socket first (its database cleanly);
849
+ // the task's /End below would be TerminateProcess.
850
+ await exitSupervisor(ctx).catch((error) => { throw new Error(`The running service could not be stopped to restart it: ${error.message}.`); });
851
+ try {
852
+ await registerWindowsTask((cmd, argv) => exec(cmd, argv, { env: nativeEnvironment(ctx.env), windowsHide: true }), windowsTaskName(label), windowsTaskXmlFile(ctx.data));
853
+ }
854
+ catch (error) {
855
+ const detail = error instanceof Error ? error.message : String(error);
856
+ throw new Error(`Task Scheduler could not start the service (${detail.trim()}). Run buddi --no-service to start it in this window instead.`);
857
+ }
858
+ console.log(`Background service: Task Scheduler task ${windowsTaskName(label)} (starts at sign-in)`);
642
859
  return;
643
860
  }
644
861
  if (!temporary && process.platform !== 'darwin')
645
- throw new Error('Background installation runs under launchd (macOS) or systemd (Linux). Use buddi --no-service or buddi supervise on this platform.');
862
+ throw new Error('Background installation runs under launchd (macOS), systemd (Linux) or Task Scheduler (Windows). Use buddi --no-service or buddi supervise on this platform.');
646
863
  const log = await open(path.join(ctx.data, 'logs/supervisor.log'), 'a', 0o600);
647
864
  try {
648
- const child = spawn(process.execPath, [entry, 'supervise'], { detached: true, stdio: ['ignore', log.fd, log.fd], env: ctx.env });
865
+ const child = spawn(process.execPath, [entry, 'supervise'], { detached: true, stdio: ['ignore', log.fd, log.fd], env: ctx.env, windowsHide: true });
649
866
  await new Promise((resolve, reject) => { child.once('spawn', resolve); child.once('error', reject); });
650
867
  child.unref();
651
868
  }
@@ -653,6 +870,27 @@ async function launchService(ctx, temporary) {
653
870
  await log.close();
654
871
  }
655
872
  }
873
+ /**
874
+ * Where a supervisor started by the Windows task writes its output
875
+ * (windows-task.ts). The task's own redirection would hold the log open
876
+ * without letting another process append, and an upgrade's successor appends
877
+ * to the same file; so the supervisor opens it itself, as node opens files,
878
+ * shared.
879
+ */
880
+ const SUPERVISOR_LOG_VAR = 'BUDDI_SUPERVISOR_LOG';
881
+ function appendOutputTo(file) {
882
+ const fd = openSync(file, 'a', 0o600);
883
+ for (const stream of [process.stdout, process.stderr]) {
884
+ stream.write = ((chunk, encoding, done) => {
885
+ try {
886
+ writeSync(fd, typeof chunk === 'string' ? Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8') : chunk);
887
+ }
888
+ catch { /* a log that cannot be written is not a reason to stop */ }
889
+ (typeof encoding === 'function' ? encoding : done)?.();
890
+ return true;
891
+ });
892
+ }
893
+ }
656
894
  async function run() {
657
895
  let ctx = await environment(root);
658
896
  // A supervisor started through buddi.app's command line tool would compete with the app's own (cli-shim.ts).
@@ -661,13 +899,22 @@ async function run() {
661
899
  process.exitCode = 2;
662
900
  return;
663
901
  }
664
- if (args[0] === 'supervise')
902
+ if (args[0] === 'supervise') {
903
+ const logFile = (process.env[SUPERVISOR_LOG_VAR] ?? '').trim();
904
+ if (logFile !== '')
905
+ appendOutputTo(logFile);
665
906
  return supervise(ctx);
907
+ }
666
908
  if (args[0] === '__gateway') {
667
909
  // Parent death must not leave two gateways claiming jobs on the next boot.
668
910
  if (!process.send)
669
911
  throw new Error('The gateway child must be started by buddi supervise.');
670
- const parentGone = () => process.kill(process.pid, 'SIGTERM');
912
+ // On Windows a kill is TerminateProcess, so the gateway's SIGTERM handler
913
+ // is run directly: it is also how the supervisor stops it there (stopChild).
914
+ const parentGone = () => { if (process.platform === 'win32')
915
+ process.emit('SIGTERM', 'SIGTERM');
916
+ else
917
+ process.kill(process.pid, 'SIGTERM'); };
671
918
  process.once('disconnect', parentGone);
672
919
  const gateway = await import('@buddi/gateway');
673
920
  try {
@@ -754,9 +1001,14 @@ async function run() {
754
1001
  process.exitCode = 1;
755
1002
  return;
756
1003
  }
757
- console.log(`tail -F ${logs.join(' ')} (Ctrl-C to stop)`);
1004
+ const windows = process.platform === 'win32';
1005
+ console.log(`${windows ? 'Following' : 'tail -F'} ${logs.join(' ')} (Ctrl-C to stop)`);
758
1006
  await new Promise(resolve => {
759
- const child = spawn('tail', ['-n', '80', '-F', ...logs], { stdio: 'inherit' });
1007
+ // Windows has no tail: a PowerShell loop follows the same files (windows-task.ts).
1008
+ const follow = windows ? followLogsCommand(logs) : undefined;
1009
+ const child = follow !== undefined
1010
+ ? spawn('powershell.exe', follow.args, { stdio: 'inherit', env: { ...process.env, ...follow.env } })
1011
+ : spawn('tail', ['-n', '80', '-F', ...logs], { stdio: 'inherit' });
760
1012
  child.once('exit', () => resolve());
761
1013
  child.once('error', err => { console.error(`buddi: could not follow the log: ${err.message}`); resolve(); });
762
1014
  });
@@ -771,7 +1023,12 @@ async function run() {
771
1023
  return entry;
772
1024
  } })();
773
1025
  console.log(`This buddi: ${invoked} (Node ${process.execPath})`);
774
- console.log(`From: ${insideAppBundle(root) ? `buddi.app (${root.slice(0, root.indexOf('.app/') + 4)})` : root.startsWith(path.join(ctx.data, 'releases') + path.sep) ? `an update buddi.app installed (${root})` : `npm (${root})`}`);
1026
+ const linux = isLinuxInstall(ctx);
1027
+ const windows = isWindowsInstall(ctx);
1028
+ console.log(`From: ${insideAppBundle(root) ? `buddi.app (${root.slice(0, root.indexOf('.app/') + 4)})` : linux ? `the Linux install (${root})` : windows ? `the Windows install (${root})` : root.startsWith(path.join(ctx.data, 'releases') + path.sep) ? `an update buddi.app installed (${root})` : `npm (${root})`}`);
1029
+ // Which Node and which npm: the bundled runtime, or the machine's (roadmap: no dependence on a host Node).
1030
+ for (const line of runtimeLines(await runtimeFacts(), insideAppBundle(process.execPath) ? 'buddi.app' : linux ? 'the Linux install' : windows ? 'the Windows install' : 'this installation'))
1031
+ console.log(line);
775
1032
  for (const line of shimDoctorLines({ home: os.homedir(), exists: existsSync, read: file => { try {
776
1033
  return readFileSync(file, 'utf8');
777
1034
  }
@@ -801,7 +1058,7 @@ async function run() {
801
1058
  * looking at a supervisor that is barely up. The file is the record.
802
1059
  */
803
1060
  const state = await readUpgradeState(ctx.data, await installedVersion(root));
804
- for (const line of upgradeDoctorLines(withApp(versionView(state), ctx), ctx.state?.phase))
1061
+ for (const line of upgradeDoctorLines(withApp(versionView(state), ctx), ctx.state?.phase, { linux, windows }))
805
1062
  console.log(line);
806
1063
  console.log(`Logs: ${path.join(ctx.data, 'logs')}`);
807
1064
  return;
@@ -873,7 +1130,7 @@ async function run() {
873
1130
  * (a foreground `buddi supervise`) the owner is told to restart it.
874
1131
  */
875
1132
  if (ctx.state !== undefined && askedWebPort !== undefined && askedWebPort !== ctx.state.webPort) {
876
- const serviced = process.platform === 'darwin' ? existsSync(launchAgentPlist(ctx.data)) : process.platform === 'linux' ? existsSync(systemdUnitPath(ctx.data, ctx.env)) : false;
1133
+ const serviced = process.platform === 'darwin' ? existsSync(launchAgentPlist(ctx.data)) : process.platform === 'linux' ? existsSync(systemdUnitPath(ctx.data, ctx.env)) : process.platform === 'win32' ? existsSync(windowsTaskScript(ctx.data)) : false;
877
1134
  if (!serviced)
878
1135
  throw new Error(`The dashboard port is ${ctx.state.webPort}. To move it to ${askedWebPort}, stop the running supervisor, change "webPort" in ${path.join(ctx.data, 'installation.json')}, and start it again.`);
879
1136
  const from = ctx.state.webPort;
@@ -884,11 +1141,13 @@ async function run() {
884
1141
  relaunched = true;
885
1142
  }
886
1143
  else {
887
- try {
888
- const status = await control(ctx);
1144
+ // A missing supervisor is normal on first run; one that holds the lock is
1145
+ // waited for, and if it never answers that is said, not restarted over.
1146
+ const status = await runningOrStarting(() => control(ctx), () => supervisorLockPid(ctx.data));
1147
+ if (status !== undefined) {
889
1148
  if (status.installRoot === root && status.nodePath === process.execPath) {
890
1149
  if (status.gateway === 'stopped')
891
- await control(ctx, 'start');
1150
+ await control(ctx, 'start').catch(() => undefined);
892
1151
  running = true;
893
1152
  }
894
1153
  else if (runsFromApp(status, ctx) && (!isAppInstall(ctx) || viaShim)) {
@@ -897,14 +1156,13 @@ async function run() {
897
1156
  running = true;
898
1157
  }
899
1158
  }
900
- catch { /* A missing supervisor is normal on first run. */ }
901
1159
  }
902
1160
  // The shim never installs a service beside buddi.app (it opened the app above).
903
1161
  if (!running && viaShim)
904
1162
  throw new Error('buddi.app is not running buddi. Open buddi.app, then run buddi again.');
905
1163
  if (!running) {
906
1164
  if (!relaunched) {
907
- console.log('Starting Buddi. First run provisions a private Postgres cluster.');
1165
+ console.log(firstRun ? 'Starting Buddi. First run provisions a private Postgres cluster.' : 'Starting buddi.');
908
1166
  await launchService(ctx, args.includes('--no-service'));
909
1167
  }
910
1168
  const deadline = Date.now() + 120_000;
@@ -959,6 +1217,34 @@ async function run() {
959
1217
  console.log(gateway.browserLine(found));
960
1218
  if (!args.includes('--no-open') && process.platform === 'darwin')
961
1219
  await exec('open', [url], { env: nativeEnvironment(ctx.env) });
1220
+ // Windows: the default browser, through the URL handler (no shell, so the link's `&` stays the link's).
1221
+ if (!args.includes('--no-open') && process.platform === 'win32') {
1222
+ const opened = await new Promise(resolve => {
1223
+ const child = spawn('rundll32.exe', ['url.dll,FileProtocolHandler', url], { detached: true, stdio: 'ignore', env: nativeEnvironment(process.env), windowsHide: true });
1224
+ child.once('error', () => resolve(false));
1225
+ child.once('spawn', () => { child.unref(); resolve(true); });
1226
+ });
1227
+ if (opened)
1228
+ console.log('Opened it in your browser.');
1229
+ }
1230
+ /*
1231
+ * On a Linux desktop the link opens in the owner's browser, as `open` does
1232
+ * on a Mac: only from a graphical session (a terminal on the desktop has
1233
+ * DISPLAY or WAYLAND_DISPLAY; an SSH shell has neither, and a browser
1234
+ * popping up on a screen nobody is looking at helps no one).
1235
+ */
1236
+ if (!args.includes('--no-open') && process.platform === 'linux' && (process.env.DISPLAY || process.env.WAYLAND_DISPLAY)) {
1237
+ const opened = await new Promise(resolve => {
1238
+ // The OS context and the desktop session's own variables only: never the .env secrets or the vault key.
1239
+ const desktop = ['DISPLAY', 'WAYLAND_DISPLAY', 'XAUTHORITY', 'XDG_RUNTIME_DIR', 'DBUS_SESSION_BUS_ADDRESS', 'XDG_CURRENT_DESKTOP', 'XDG_SESSION_TYPE', 'XDG_SESSION_DESKTOP', 'DESKTOP_SESSION', 'XDG_DATA_DIRS', 'XDG_CONFIG_DIRS', 'XDG_DATA_HOME', 'XDG_CONFIG_HOME', 'BROWSER'];
1240
+ const env = { ...nativeEnvironment(process.env), ...Object.fromEntries(desktop.filter(key => typeof process.env[key] === 'string').map(key => [key, process.env[key]])) };
1241
+ const child = spawn('xdg-open', [url], { detached: true, stdio: 'ignore', env });
1242
+ child.once('error', () => resolve(false));
1243
+ child.once('spawn', () => { child.unref(); resolve(true); });
1244
+ });
1245
+ if (opened)
1246
+ console.log('Opened it in your browser.');
1247
+ }
962
1248
  return;
963
1249
  }
964
1250
  if (!wantsHelp && args[0] === 'backup' && (args[1] === 'restore' || args[1] === 'create')) {